Click here to Skip to main content
15,912,329 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a linq query in a foreach loop with some if clauses
I wanted you to help me how can I write them all in a query (not using foreach)
Number is a big table that I need to divide each line of it to four A,B,C,D and search them in another table and find the similars


C#
ret = new List<ReportData>();
    foreach (var item in Number)
    {
        string A = item.Substring(0, 11);
        string B = item.Substring(14, 2);
        string C = item.Substring(19, 11);
        string D = item.Substring(33);
        ret1 = (from a in Report
                where a.A == A && a.B == B
                && a.C == C && a.D == D &&   
                Filter.Type.Contains(a.Y)
                select new ReportData
                {
                    X = a.X,
                    Y = a.Y,
                });
      
       if (Filter.Ma != null && Filter.Ma.Count > 0)
          {
             ret1 = ret1.Where(z => Filter.Ma.Contains(z.Ma));
          }
       if (ret1 != null && ret1.ToList().Count > 0)
          {
             ret.AddRange(ret1);
          }
}
Posted
Updated 16-Jul-15 5:01am
v2

1 solution

I hate linq syntax. I use extension syntax so I can build up queries to refine them.

Either way - This is my stab:

C#
var ret = Number.Select(item => new
{
    A = item.Substring(0, 11),
    B = item.Substring(14, 2),
    C = item.Substring(19, 11),
    D = item.Substring(33)
})
.SelectMany(n =>
    Report.Where(
        a => a.A == n.A && a.B == n.B
        && a.C == n.C && a.D == n.D &&
        Filter.Type.Contains(a.Y))
    .Select(a => new ReportData
        {
            X = a.X,
            Y = a.Y,
        }))
.Where(nr =>
    Filter.Ma == null || !Filter.Ma.Any() || Filter.Ma.Contains(nr.Ma)
).ToList();



I couldn't really test it as I don't know what Report, Filter or ReportData, really look like


Update: Broken down into stages:

C#
//Must be a var as the type is anonymous
var q1 = Number.Select(item => new
{
    A = item.Substring(0, 11),
    B = item.Substring(14, 2),
    C = item.Substring(19, 11),
    D = item.Substring(33)
}).AsQueryable(); //Not a requirement but should help optimize


//Select many is pretty darn optimal.  I don't see you getting a better return that this
var q2 = q1.SelectMany(n =>
    Report.Where(
        a => a.A == n.A && a.B == n.B
        && a.C == n.C && a.D == n.D &&
        Filter.Type.Contains(a.Y))
    .Select(a => new ReportData
        {
            X = a.X,
            Y = a.Y,
        })).AsQueryable();

//If the return type is the same a previous variable then you can reuse it.
var ret = q2.Where(nr =>
    Filter.Ma == null || !Filter.Ma.Any() || Filter.Ma.Contains(nr.Ma)
).ToList();
 
Share this answer
 
v2
Comments
Lalyka 16-Jul-15 12:08pm    
Thanks a lot, it is working but may I know if it is possible to implement this
.Where(nr =>
Filter.Ma == null || !Filter.Ma.Any() || Filter.Ma.Contains(nr.Ma)
before.select?
and if I want to implement more than one if condition what should I do?
Andy Lanng 16-Jul-15 12:12pm    
I don't see how. The object 'nr' is a direct result of the select. If "Ma" is something you can calculate or get without instantiating ReportData, then yes, you can.

The order shouldn't matter. It will get normalized automatically. The whole thing should only execute on "ToList()"

(ps. really? it worked without tweaks? I knew I was good but that surprised me ^_^ )
Lalyka 16-Jul-15 12:14pm    
I am worried for the order because I need to optimize it, my first solution was so slow.
Andy Lanng 16-Jul-15 12:19pm    
yes but linq is self, optimizing. The extension methods to not execute one by one, but make up a single query that it only executed when ToArray, or ToList or some other specific extension requires it.

It's easy to break it down though. I'll update the solution in a way that is easier to tinker with.

If you manage to get data for the where cause before the select then I would like to know if you do actually see any improvement ^_^
Lalyka 17-Jul-15 3:41am    
Hi Andy

actually yesterday I was testing to see if teh query returns the right results but it does not, I want it to seach the database for every Filter.Type that in in a.Y
is it Filter.Type.Contains(a.Y)) the right command thoght?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900