How to replace normal foreach to linq ForEach? - c#

public static List<TDuplicate> ValidateColumnInList<TItem, TDuplicate>(List<TDuplicate> DuplicateExpression) where TDuplicate : DuplicateExpression
{
List<TDuplicate> TempDuplicateExpression = new List<TDuplicate>();
var itemProperties = typeof(TItem).GetProperties();
foreach (var DplExpression in DuplicateExpression)
{
bool IsContainColumn = itemProperties.Any(column => column.Name == DplExpression.ExpressionName);
if (!IsContainColumn)
{
TempDuplicateExpression.Add(DplExpression);
}
}
return TempDuplicateExpression;
}
In the above section how to replace above foreach to linq ForEach.

You do not need foreach or ForEach here. Below code should give you result:
var itemProperties = typeof(TItem).GetProperties();
List<TDuplicate> tempDuplicateExpression = DuplicateExpression
.Where(m => !itemProperties.Any(column => column.Name == m.ExpressionName))
.ToList();
return tempDuplicateExpression;

You can get result by this simple way:
var result = DuplicateExpression.Where(n=>!itemProperties.Any(column => column.Name == n.ExpressionName)).ToList();
Or you can user ForEach like this:
DuplicateExpression.ForEach(n=>
{
bool IsContainColumn = itemProperties.Any(column => column.Name == n.ExpressionName);
if (!IsContainColumn)
{
TempDuplicateExpression.Add(n);
}
}
)

Related

How to simplify if condition and foreach condition in c#.net?

I have a repeating foreach condition in my controller. How can I simplify it?
I almost reach 500 lines because of this. I've been using this for x8 each condition.
List<jewelry_dashboard_view_per_month> transactionmonthlynewloan = dashboardmanager.Get_MonthlyTransaction(search_branch, (monthlyonly + "01"), "N-", (monthlyonly + no_of_items), no_of_items, monthlyonly);
myNewLoanMontlyList.Add(transactionmonthlynewloan);
List<jewelry_dashboard_view_per_month> transactionmonthlyrenewal = dashboardmanager.Get_MonthlyTransaction(search_branch, (monthlyonly + "01"), "R-", (monthlyonly + no_of_items), no_of_items, monthlyonly);
myRenewalMontlyList.Add(transactionmonthlyrenewal);
This is the if condition
if (myNewLoanMontlyList[0].Count != 0)
{
foreach (var internal_monthly_newloan_data in myNewLoanMontlyList[0].SelectMany(c => c.id_data))
{monthly_newloan_data_ID.Add(internal_monthly_newloan_data);}
foreach (var internal_monthly_newloan_data in myNewLoanMontlyList[0].SelectMany(c => c.debit_data))
{monthly_newloan_data_debit.Add(internal_monthly_newloan_data);}
}
else
{
monthly_newloan_data_ID.Add(0);
monthly_newloan_data_debit.Add(0);
};
and this is the foreach condition
//newloan
int newloan_data_id = 0;
DateTime newloan_data_transdate = DateTime.Parse((DateTime.Today).ToString());
decimal newloan_data_debit = 0;
string newloan_data_txnname = "";
string newloan_data_branchID = "";
foreach (var newloan_data in newloan)
{
newloan_data_id = newloan_data.ID;
newloan_data_transdate = DateTime.Parse((newloan_data.Transdate).ToString());
newloan_data_debit = Decimal.Parse((newloan_data.Debit).ToString());
newloan_data_txnname = newloan_data.TransactionName;
newloan_data_branchID = newloan_data.BranchID;
};
datanewloan = new transaction_details()
{
ID = newloan_data_id,
Transdate = DateTime.Parse(newloan_data_transdate.ToString("yyyy-MM-dd")),
Debit = Decimal.Parse(newloan_data_debit.ToString()),
TransactionName = newloan_data_txnname,
BranchID = newloan_data_branchID
};
In Your scenario of if-else conditions:
if (myNewLoanMontlyList[0].Count != 0)
{
foreach (var internal_monthly_newloan_data in myNewLoanMontlyList[0].SelectMany(c => c.id_data))
{monthly_newloan_data_ID.Add(internal_monthly_newloan_data);}
foreach (var internal_monthly_newloan_data in myNewLoanMontlyList[0].SelectMany(c => c.debit_data))
{monthly_newloan_data_debit.Add(internal_monthly_newloan_data);}
}
else
{
monthly_newloan_data_ID.Add(0);
monthly_newloan_data_debit.Add(0);
};
If in the method, there is no other process after the if-else, you can use only if condition without the else part.
if (myNewLoanMontlyList[0].Count == 0)
{
monthly_newloan_data_ID.Add(0);
monthly_newloan_data_debit.Add(0);
}
foreach (var internal_monthly_newloan_data in myNewLoanMontlyList[0].SelectMany(c => c.id_data))
{monthly_newloan_data_ID.Add(internal_monthly_newloan_data);}
foreach (var internal_monthly_newloan_data in myNewLoanMontlyList[0].SelectMany(c => c.debit_data))
{monthly_newloan_data_debit.Add(internal_monthly_newloan_data);}
You can use Linq,
SelectMany: Projects each element of a sequence to an IEnumerable<T>. You need not to iterate again and add it to separate list
For your if condition look like,
if (myNewLoanMontlyList[0].Any())
{
monthly_newloan_data_ID = myNewLoanMontlyList[0].SelectMany(c => c.id_data);
monthly_newloan_data_debit = myNewLoanMontlyList[0].SelectMany(c => c.debit_data);
}
else
{
monthly_newloan_data_ID.Add(0);
monthly_newloan_data_debit.Add(0);
}
Select: Projects each element of a sequence into a new form. In your
case new form is instance of transaction_details
Instead of for loop use Linq .Select(),
var result = newloan.Select(x => new transaction_details(){
ID = x.ID,
Transdate = DateTime.Parse(x.Transdate.ToString("yyyy-MM-dd")),
Debit = Decimal.Parse((x.Debit).ToString()),
TransactionName = x.TransactionName,
BranchID = x.BranchID
}).LastOrDefault();
To get last element, I used LastOrDefault(). You can get individual element by index or by condition.

How to fix : Cannot convert lambda expression to type int because is not delegate?

i am trying to get user decision from the list but i get that Cannot convert lambda expression to type int because is not delegate. How can i solve this? I have had a look on the internet but since i am quite new i am not sure what is the right solution
public static List<int> UserDecisionResult { get; set; }
public void GetUserDecision()
{
List<int> userDecision = new List<int>();
if (FilterAllItems) userDecision.Add(_parentCategoryId = -1);
if (FilterBeginnerItems) userDecision.Add(_parentCategoryId = 1);
if (FilterIntermediateItems) userDecision.Add(_parentCategoryId = 2);
if (FilterUpperIntermediateItems) userDecision.Add(_parentCategoryId = 3);
if (FilterAdvancedItems) userDecision.Add(_parentCategoryId = 4);
UserDecisionResult = userDecision;
}
private static List<Article> FindAllArticlesForPurchase(List<Article> allArticles)
{
var result = UserDecisionResult;
if (_parentCategoryId != -1)
{
foreach (var categoryGroup in _allUserCategoryGroups)
{
var allGroupCategories = _allCategories.Where(m => m.CategoryGroupId == categoryGroup.Id).ToList();
if (_parentCategoryId != -1)
{
foreach (var category in allGroupCategories)
{
if (category.ParentId == _parentCategoryId && _parentCategoryId != -1)
{
var categoryArticles = _allArticlesForPurchase.Where(result.Contains(m => m.CategoryId == category.Id).ToList();
//var categoryArticles = _allArticlesForPurchase.Where(result.Contains(m => m.CategoryId == category.Id).ToList());
allArticles.AddRange(categoryArticles);
}
}
}
}
}
else
{
allArticles = _allArticlesForPurchase;
}
return allArticles;
}
Your lambda expression is wrong here due to syntax. You can try:
var categoryArticles = _allArticlesForPurchase
.Where(m => m.CategoryId == category.Id
&& result.Contains(m.CategoryId))
.ToList();
or if Contains here is some custom implementation then try :
var categoryArticles = _allArticlesForPurchase
.Where(_ => result.Contains(m => _.CategoryId == category.Id))
.ToList();

How to assign "var" inside if statement

I need to do this:
var productsLocation = response.blah blah; //with linq query
var item; // even var item = null; //not valid
if(condition){
item = productsLocation.linq query
} else {
item = productsLocation.differentquery
}
var group = item.query;
Is this possible? If yes, how?
EDIT: here is my exact code:
var productLocation = response.productLocation.Select(p => ProductLocationStaticClass.DtoToModel(p));
var items;
if (condition)
{
items = productLocation.Select(s => new ProductClass(s)).Where(s => categories.Contains(s.CategoryName));
} else {
items = productLocation.Select(s => new ProductClass(s)).Where(s => categories.Contains(s.CategoryName) && stocks.Contains(s.Barcode));
}
If you look closely at the logic, you notice you don't actually even need the if block. The whole thing can be written in one expression as follows:
var items = productLocation
.Select(s => new ProductClass(s))
.Where(s => categories.Contains(s.CategoryName) && (condition || stocks.Contains(s.Barcode)));
First of all get your response variable type, then initialize 'item' variable as IEnumarable where T is same as response variable type
var productsLocation = response.productLocation.Select(p => ProductLocationStaticClass.DtoToModel(p));
IEnumerable<ProductClass> item;
if (condition)
{
items = productLocation.Select(s => new ProductClass(s)).Where(s => categories.Contains(s.CategoryName));
}
else
{
items = productLocation.Select(s => new ProductClass(s)).Where(s => categories.Contains(s.CategoryName) && stocks.Contains(s.Barcode));
}
var group = item.Where(condition);
You can do it with IEnumerable interface in this way:
using System.Collections;
using System.Collections.Generic;
List<string> products = new List<string>() { "First", "Second", "Third", "Fourth" };
IEnumerable item;
var condition = false;
if (condition)
{
item = products.Select(x=>x);
}
else
{
item = products.Where(x => x.StartsWith("F"));
}
var group = item.Cast<string>().Where(/*...Here your conditions...*/)

convert foreach and if to linq queries

foreach (SchemaInfo db in SourceSchemaInfos)
{
foreach (SchemaInfo table in db.SchemaInfos)
{
foreach (SchemaInfo tablelist in table.SchemaInfos)
{
for (int i = 0; i < SelectedTables.Count; i++)
{
if (tablelist.Key == SelectedTables[i].Key)
{
foreach (SchemaInfo _tableschema in tablelist.SchemaInfos)
{
_tableschema.IsSelected = true;
}
}
}
}
}
}
i tried to convert the above foreach loop into linq queries as below..
SourceSchemaInfos.ForEach(Database =>Database.SchemaInfos.ForEach(items => items.SchemaInfos.ForEach(tables => tables.SchemaInfos.Where(tables.Key == SelectedTables.ForEach(l => l.Key)).ForEach(m => m.IsSelected = true))));
but it thorws me the below error # l.Key
CS0201 Only assignment, call, increment, decrement, and new object expressions can be used as a statement
`
Try the following code. I think this is correct LINQ conversion of your query
foreach (var _tableschema in
(from db in SourceSchemaInfos from table in db.SchemaInfos from tablelist in table.SchemaInfos
select tablelist)
.SelectMany(tablelist => SelectedTables.Where(t => tablelist.Key == t.Key)
.SelectMany(t => tablelist.SchemaInfos)
))
{
_tableschema.IsSelected = true;
}
var schemaInfos = from db in SourceSchemaInfos
from table in db.SchemaInfos
from tableList in table.SchemaInfos
from selectedTable in SelectedTables
where tableList.Key == selectedTable.Key
select tableList.SchemaInfos;
foreach(var tableSchema in schemaInfos)
{
tableSchema.IsSelected = true;
}

Refactoring similar methods using generics parameter in c# and linq

I have two methods they are exactly the same except the first parameter.I don't want to repeat the duplicate code. I was wondering how can we refactor the following code using generic parameters.
First method
private Dictionary<List<string>, List<string>> GetFinancialLtmDataSet(List<sp_get_company_balance_sheet_amount_ltm_Result> itemResult, int neededyear)
{
var requestedData =
itemResult.OrderByDescending(x => x.date.Year).Take(neededyear).Select(x => new { date = x.date.Date });
var addFields = new List<string>();
var dataSet = new Dictionary<List<string>, List<string>>();
int counter = 0;
foreach (var itemy in requestedData)
{
var skipvalue = itemResult.Skip(counter);
var columns = skipvalue.OrderBy(x => itemy.date).ToList();
var cc = columns.First();
counter++;
var properties =
cc.GetType()
.GetProperties()
.Select(x => new { Name = x.Name, Value = x.SetMethod, a = x.GetValue(cc, null) })
.ToList();
foreach (var property in properties)
{
addFields.Add(property.Name);
if (property.a != null)
{
dataSet.Add(new List<string> { property.Name }, new List<string> { property.a.ToString() });
}
}
}
return dataSet;
}
Second method
private Dictionary<List<string>, List<string>> GetFinancialQuartelyDataSet(List<sp_get_company_balance_sheet_amount_quaterly_Result> itemResult, int neededyear)
{
var requestedData =
itemResult.OrderByDescending(x => x.date.Year).Take(neededyear).Select(x => new { date = x.date.Date });
var addFields = new List<string>();
var dataSet = new Dictionary<List<string>, List<string>>();
int counter = 0;
foreach (var itemy in requestedData)
{
var skipvalue = itemResult.Skip(counter);
var columns = skipvalue.OrderBy(x => itemy.date).ToList();
var cc = columns.First();
counter++;
var properties =
cc.GetType()
.GetProperties()
.Select(x => new { Name = x.Name, Value = x.SetMethod, a = x.GetValue(cc, null) })
.ToList();
foreach (var property in properties)
{
addFields.Add(property.Name);
if (property.a != null)
{
dataSet.Add(new List<string> { property.Name }, new List<string> { property.a.ToString() });
}
}
}
return dataSet;
}
I have created a following method to make it generic but not been able to get the final implementation any suggestion appreciated.
private List<T> GetFinancialReport<T>(List<T> data, int neededyear)
{
//what should I return from here
return data;
}
and would like to use the above method like this
var balancesheetResult=balancesheet.ToList();
var testData = GetFinancialReport<BalanceSheet_sp>(balancesheetResult, 5);
var cashflowresult=cashflow.ToList();
var testData1 = GetFinancialReport<CahsFlow_sp>(cashflowresult, 10);
From what is shown above the objects (at least the properties involved) match. So you could code against an interface here:
private Dictionary<List<string>, List<string>> GetFinancialReport(List<IBalance>, int neededyear)
{
...
}

Categories