patterncsharpMinor
Determining which accounts are to be credited/debited
Viewed 0 times
determiningarewhichcreditedaccountsdebited
Problem
I recently discovered/came across linq and have been trying to learn and utilize its features. Here's my first function
After I have populated the dictionary properties with the transaction amounts, I use Linq to first remove all the transactions with amount 0 and then to generate XML elements to represent the transactions (provided a sample of the output).
The code works. Am I using LINQ right? Is the code optimal? Can I improve the LINQ code? Should I even be using it?
XmlOutput
PurchaseDocument.cs
`public class PurchaseDocument
{
public Dictionary DebitTransactions = new Dictionary();
public Dictionary CreditTransactions = new Dictionary();
public Dictionary InventoryTransactions = new Dictionary();
#region public ObservableCollection Items;
private ObservableCollection _Items = new ObservableCollection();
public ObservableCollection Items
{
get { return _Items; }
set
{
string property = "Items";
OnPropertyChanging(property);
_Items = value;
OnPropertyChanged(property);
}
}
#endregion
private void UpdateTransactionsData()
{
DebitTransactions.Clear();
CreditTransactions.Clear();
InventoryTransactions.Clear();
Entity.TransactionsData = "";
foreach (PurchaseDocumentItem item in Items.Where(x => x.InventoryItem != null))
{
// asset and expense transactions
int account = (item.InventoryItem.IsService) ? item.InventoryItem.CogsAccountID : item.InventoryItem.AssetAccountID;
if(!DebitTransactions.ContainsKey(account))
DebitTransact
UpdateTransactionsData(). This method is for a PurchaseDocument class which I have included partially. Basically this function loops through the selected items on the PurchaseDocument, and works out which accounts (chart of accounts, as per accounting) are to be credited/debited for each purchased item. After I have populated the dictionary properties with the transaction amounts, I use Linq to first remove all the transactions with amount 0 and then to generate XML elements to represent the transactions (provided a sample of the output).
The code works. Am I using LINQ right? Is the code optimal? Can I improve the LINQ code? Should I even be using it?
XmlOutput
PurchaseDocument.cs
`public class PurchaseDocument
{
public Dictionary DebitTransactions = new Dictionary();
public Dictionary CreditTransactions = new Dictionary();
public Dictionary InventoryTransactions = new Dictionary();
#region public ObservableCollection Items;
private ObservableCollection _Items = new ObservableCollection();
public ObservableCollection Items
{
get { return _Items; }
set
{
string property = "Items";
OnPropertyChanging(property);
_Items = value;
OnPropertyChanged(property);
}
}
#endregion
private void UpdateTransactionsData()
{
DebitTransactions.Clear();
CreditTransactions.Clear();
InventoryTransactions.Clear();
Entity.TransactionsData = "";
foreach (PurchaseDocumentItem item in Items.Where(x => x.InventoryItem != null))
{
// asset and expense transactions
int account = (item.InventoryItem.IsService) ? item.InventoryItem.CogsAccountID : item.InventoryItem.AssetAccountID;
if(!DebitTransactions.ContainsKey(account))
DebitTransact
Solution
I don't see any problem with the LINQ you have.
If you wanted, you could use a little bit of LINQ to get rid of that foreach loop you have. You can create two LINQ queries to query the Items collection, group accounts/items together, and return the sum of the Amounts/Quantities as a Dictionary:
It's a little more messy and probably a little less efficient, but good for learning LINQ.
If you wanted, you could use a little bit of LINQ to get rid of that foreach loop you have. You can create two LINQ queries to query the Items collection, group accounts/items together, and return the sum of the Amounts/Quantities as a Dictionary:
DebitTransactions = (from item in Items
where item.InventoryItem != null
let account = (item.InventoryItem.IsService) ? item.InventoryItem.CogsAccountID : item.InventoryItem.AssetAccountID
group item by account into itemGroup
select new
{
Account = itemGroup.Key,
Amount = itemGroup.Sum(i => i.Amount)
}).ToDictionary(k => k.Account, v => v.Amount);
InventoryTransactions = (from item in Items
where item.InventoryItem != null && !item.InventoryItem.IsService
group item by item.ItemID into itemGroup
select new
{
ItemID = itemGroup.Key
Quantity = itemGroup.Sum(i => i.Quantity)
}).ToDictionary(k => k.ItemID, v => v.Quantity);It's a little more messy and probably a little less efficient, but good for learning LINQ.
Code Snippets
DebitTransactions = (from item in Items
where item.InventoryItem != null
let account = (item.InventoryItem.IsService) ? item.InventoryItem.CogsAccountID : item.InventoryItem.AssetAccountID
group item by account into itemGroup
select new
{
Account = itemGroup.Key,
Amount = itemGroup.Sum(i => i.Amount)
}).ToDictionary(k => k.Account, v => v.Amount);
InventoryTransactions = (from item in Items
where item.InventoryItem != null && !item.InventoryItem.IsService
group item by item.ItemID into itemGroup
select new
{
ItemID = itemGroup.Key
Quantity = itemGroup.Sum(i => i.Quantity)
}).ToDictionary(k => k.ItemID, v => v.Quantity);Context
StackExchange Code Review Q#4364, answer score: 2
Revisions (0)
No revisions yet.