convert foreach and if to linq queries - c#

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;
}

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.

can not convert from System.Collection.Generic.List<Dal.Questio> to Dal.Questio

I want to append my list into another list but when i do this i got the error
How can it be solved?
public List<Questio> Get(int Id)
{
List<Questio> Quest;
Quest = null;
try
{
using (db = new Entities())
{
var Qu = db.Que.Where(x => x.Lan == Id).Select(i => i.Id);
foreach (var a in Qu)
{
var ID = db.Quess.Where(x => x.QueId == a).Select(i => i.Qued);
foreach (var j in ID)
{
var vv = db.Questio.Where(m => m.QId == j).ToList();
Quest.Add(vv);
}
}
}
}
}
You just need to use AddRange that accepts IEnumerable:
Quest.AddRange(vv);
Add is for adding a single item only.
If what you actually need is a list of lists, then declare Quest differently:
List<List<Questio>> Quest = new List<List<Questio>>();
...
var vv = db.Questio.Where(m => m.QId == j).ToList();
Quest.Add(vv);
Now your call to Add should work fine.
Two side notes, both beyond the scope of the question: 1) as the comments say, please review your naming; 2) this code could be simplified with more LINQ features, like Join and SelectMany.

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...*/)

How to replace normal foreach to linq ForEach?

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);
}
}
)

The LINQ expression node type 'ArrayIndex' is not supported in LINQ to Entities

public List<string> GetpathsById(List<long> id)
{
long[] aa = id.ToArray();
long x;
List<string> paths = new List<string>();
for (int i = 0; i < id.Count; i++)
{
x = id[i];
Presentation press = context.Presentations.Where(m => m.PresId == aa[i]).FirstOrDefault();
paths.Add(press.FilePath);
}
return paths;
}
This code throws the following exception: The LINQ expression node type 'ArrayIndex' is not supported in LINQ to Entities.
However, if I supply x instead of aa[i] it works.
Why?
To fix this use a temporary variable:
var tmp = aa[i];
...
m => m.PresId == tmp
In your where clause you have
m => m.PresId == aa[i]
which is a way of expressing a lambda expression. When that is converted to an expression, then converted into a query on your database it finds the aa[i], which is an index into an array. i.e. it doesn't treat it as a constant. Since a translation of an indexer to your database language is impossible it gives the error.
Apparently, if you use an array index (aa[i]) inside an expression tree, it tries to convert that into an expression as well.
Just work around it by using a separate variable:
int presId = aa[i];
Presentation press = context.Presentations.Where(m => m.PresId == presId).FirstOrDefault();
public List<string> GetpathsById(List<long> id)
{
long[] aa = id.ToArray();
long x;
List<string> paths = new List<string>();
for (int i = 0; i < id.Count; i++)
{
x = id[i];
int temp = aa[i];
Presentation press = context.Presentations.Where(m => m.PresId == temp).FirstOrDefault();
paths.Add(press.FilePath);
}
return paths;
}
try this
It cannot be mapped to an SQL type or function.
You are aware you are mixing your list and array with each other. Everything you want doing in this code can be done simply using the list.
The following bit of code will do everything you need it to.
public List<string> GetpathsById(List<long> id)
{
long x;
List<string> paths = new List<string>();
foreach(long aa in id)
{
Presentation press = context.Presentations.Where(m => m.PresId == aa).FirstOrDefault();
paths.Add(press.FilePath);
}
return paths;
}
public List<string> GetpathsById(List<long> id)
{
long x;
List<string> paths = new List<string>();
foreach(long aa in id)
{
Presentation press = context.Presentations.Where(m => m.PresId == aa).FirstOrDefault();
paths.Add(press.FilePath);
}
return paths;
}
to
public IEnumerable<String> GetpathsById(List<long> id)
{
foreach(long item in id)
yield return = (context.Presentations.Where(m => m.PresId == item).FirstOrDefault()).FilePath
}
"Short style", but not recomended if you write a lot of other function.
Can be simplified to avoid the error:
public List<string> GetpathsById(List<long> id)
{
return context.Presentations.Where(x => id.Contains(x.PresId)).Select(x => x.FilePath).ToList();
}

Categories