简体   繁体   中英

Why can't I use an actual class in LINQ-to-SQL join method?

I am trying to do a LINQ join in C# (using EntityFramework Core 3.1.13) that uses a class in the key selector.

For example:

public class KeyClass {
       public int Key { get; set; }    
}


using (var Context = new ...Context()) {

var Query = Context.Table1.Join(Context.Table2,x => new KeyClass () { Key = x.ID }, x => new KeyClass() { Key = x.ID2 }, (x,y) => new { x, y });

}

It doesn't work when I use the KeyClass - I get an error stating the LINQ expression cannot be translated.

But if I use an anonymous type instead, it works fine:

using (var Context = new ...Context()) {

var Query = Context.Table1.Join(Context.Table2,x => new  { Key = x.ID }, x => new { Key = x.ID2 }, (x,y) => new { x, y });

}

I cannot use the anonymous type in my case because I want to be able to build the join at runtime dynamically and will need to use an emitted type for the key selector as it may have multiple keys and different types.

The reason is because the EFC translator only supports Expression.New (C# new ) constructor call with arguments rather than Expression.MemberInit (C# object initializer) for join keys.

Both anonymous types and tuples fall into the first category (event though syntactically anonymous type allocations looks like object initializer, in fact it is a constructor call of the compiler generated class - similar to the C#9 record declaration), while your class doesn't.

Knowing all that, the solution is actually quite simple - just add and use constructor to the class, eg

public class KeyClass
{
    public KeyClass(int key) => Key = key;
    public int Key { get; }    
}

or in C#9

public record KeyClass(int Key);

Now this works (translates)

var Query = Context.Table1.Join(Context.Table2,
    x => new KeyClass(x.ID), x => new KeyClass(x.ID2),
    (x, y) => new { x, y });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM