Arvis
Arvis

Reputation: 8363

Use of anonymous in LINQ

I'm trying to achieve trivial task as simple as possible: get distinct set of codes from table1 and filter out all records from table2 based on code field. I want to use benefit of LINQ and anonymous types as it will be elegant and clean code, and i'm trying to avoid making intermediate transport classes. Code could be similar to:

//In db repository
public static IQueryable DataQuery()
{
    var args = db.Table1.Select(x => new { x.Code }).Distinct();
    return db.Table2.Where(r => args.Contains(r.Code));
    // Contains extension not allow use args implicitly!
}

And calling methode:

public void GetData()
{
     var data = Repository.DataQuery(); 
     var result = data.Select(d => new 
        {
            Value = d.Code,
            Text = d.Name
        });
 // the same problem here, Select wants only explicitly specified args!
}

How can it be done proper way and cleaner as possible? Mainly, example code has 2 problems: taking anonymous as args in same method and returning its to another method/project. So what the use of anonymous if i can't use? In all tutorials I see anonymous are used as Console.WriteLine(...) of course it will works but in real life i want more that put its out on screen.

Is it only way to create new classes when i want filter out different entity subsets from bigger tables?

Known limitations:
anonymous are usable only in surrounding scope;
dynamic are useful only in same assembly;

Edited example:

public IQueryable DataQuery()
{
    return dbContext.MyModel.Select(x => new { x.Code, x.Name }).Distinct();
}

I want to return Iqueryable or ienumerable only for some interested properties in MyModel.

Upvotes: 0

Views: 143

Answers (1)

Henk Holterman
Henk Holterman

Reputation: 273244

The problems that I can see:

  1. You wrap x.Code in an unnecessary class. Just select it.
  2. You will need to return IQueryable<T>
public static IQueryable<T> DataQuery()
{
    //var args = db.Table1.Select(x => new { x.Code }).Distinct();
    var args = db.Table1.Select(x =>  x.Code ).Distinct();
    return db.Table2.Where(r => args.Contains(r.Code));
}

and now when you call it, you will have to specify a Type

public void GetData()
{
     var data = Repository.DataQuery<Table2Type>(); 
     var result = data.Select(d => new 
        {
            Value = d.Code,
            Text = d.Name
        });     
}

Anonymous types are only usable in their surrounding scope, you can not return them from a method.

Upvotes: 1

Related Questions