Lambda 表达式到表达式 <T> 树(切片 2 - 连接)
Lambda expression to Expression<T> Tree (Slice 2 - Join)
如何将大象放入冰箱?你把它切片...... Sooo,你如何将 lambda 查询转换为表达式树?你切它...
这是表达式树的一系列 3 片 lambda 表达式。
切片 1。,如何使用 Microsoft 示例执行 .join()。
切片 2(此切片)。使用与切片 1 中使用的参数不同的参数进行预加载。
切片 3。Here,如何使用 .where() 和 .Select().
完成查询
在此切片中,我尝试将以下查询转换为表达式树语法:
IQueryable<A> As = db.A
.Join(
db.B,
_a => _a.bID,
_b => _b.ID,
(a, b) => new { a, b })
//The next two statements are going to next slice.
.Where(s=> s.b.Name == "xpto")
.Select(s => s.a);
在切片 1 中我有:
上一个转换示例:
var query = people.AsQueryable().Join(pets,
person => person,
pet => pet.Owner,
(person, pet) =>
new { OwnerName = person.Name, Pet = pet.Name });
这导致了@NetMage 的回答,成功的方法是:
// Build Queryable.Join<TOuter,TInner,TKey,TResult> and use as query expression
// IQueryable<TOuter>
var arg0 = Expression.Constant(people.AsQueryable());
// IEnumerable<TInner>
var arg1 = Expression.Constant(pets);
// TOuter person
var arg2p = Expression.Parameter(people.GetType().GetGenericArguments()[0], "person");
// also TKey person
// Expression<Func<TOuter,TKey>>: person => person
var arg2 = Expression.Quote(Expression.Lambda(arg2p, arg2p));
// TInner pet
var arg3p = Expression.Parameter(pets.GetType().GetGenericArguments()[0], "pet");
// TKey pet.Owner
var arg3body = Expression.Property(arg3p, "Owner");
// Expression<Func<TInner,TKey>>: pet => pet.Owner
var arg3 = Expression.Quote(Expression.Lambda(arg3body, arg3p));
// TResult = typeof(new { string OwnerName , string Pet })
var anonymousType = (new { OwnerName = default(string), Pet = default(string) }).GetType();
// .ctor
var arg4Constructor = anonymousType.GetConstructors()[0];
// person.Name
var arg4PersonName = Expression.Property(arg2p, "Name");
// pet.Name
var arg4PetName = Expression.Property(arg3p, "Name");
var arg4Args = new[] { arg4PersonName, arg4PetName };
// new[] { .OwnerName, .Pet }
var arg4Members = anonymousType.GetProperties();
// new { OwnerName = person.Name, Pet = pet.Name }
var arg4body = Expression.New(arg4Constructor, arg4Args, arg4Members);
// Expression<Func<TOuter,TInner,TResult>>: (person,pet) => new { OwnerName = person.Name, Pet = pet.Name }
var arg4 = Expression.Quote(Expression.Lambda(arg4body, arg2p, arg3p));
var joinGenericMI = typeof(Queryable).GetMethod("Join", 5);
var joinMI = joinGenericMI.MakeGenericMethod(new[] { arg2p.Type, arg3p.Type, arg2.ReturnType, anonymousType });
var qExpr = Expression.Call(joinMI, arg0, arg1, arg2, arg3, arg4);
对于此切片,需要更改前一个切片中出现的以下语句:
// TResult = typeof(new { string OwnerName , string Pet })
var anonymousType = (new { OwnerName = default(string), Pet = default(string) }).GetType();
@NetMage 将其改编为通用 A 和 B:
// TResult = typeof(new { A , B })
var anonymousType = (new { A = db.A.FirstOrDefault(), db.B = B.FirstOrDefault() }).GetType();
和
var arg4Constructor = anonymousType.GetConstructors()[0];
// person.Name
var arg4PersonName = Expression.Property(arg2p, "Name");
// pet.Name
var arg4PetName = Expression.Property(arg3p, "Name");
变成了(适用于通用 A 和 B):
// object A
var arg4A = arg2p;
// object B
var arg4B = arg3p;
现在需要通过b.Name和Selecta(下一个切片)过滤结果。
要从 Join
方法中获取 return 类型,请执行以下操作:
// TResult = typeof(new { A , B })
var anonymousType = (new { A = db.A.FirstOrDefault(), db.B = B.FirstOrDefault() }).GetType();
您需要创建一个匿名类型,其中成员 A
具有类型 db.A
实体类型。如果你使用例如typeof(A)
,那么你将得到 A
类型 Type
,与 Join
完全无关。 (如果您知道 A
的实体类型,您可以像我一样使用 default
:例如,如果 db.A
是 DbSet<AClass>
,则使用 A = default(AClass)
。)
由于您没有引用 Join
结果中的任何属性,您只需使用参数:
// object A
var arg4A = arg2p;
// object B
var arg4B = arg3p;
如何将大象放入冰箱?你把它切片...... Sooo,你如何将 lambda 查询转换为表达式树?你切它...
这是表达式树的一系列 3 片 lambda 表达式。
切片 1。
切片 2(此切片)。使用与切片 1 中使用的参数不同的参数进行预加载。
切片 3。Here,如何使用 .where() 和 .Select().
完成查询在此切片中,我尝试将以下查询转换为表达式树语法:
IQueryable<A> As = db.A
.Join(
db.B,
_a => _a.bID,
_b => _b.ID,
(a, b) => new { a, b })
//The next two statements are going to next slice.
.Where(s=> s.b.Name == "xpto")
.Select(s => s.a);
在切片 1 中我有:
上一个转换示例:
var query = people.AsQueryable().Join(pets,
person => person,
pet => pet.Owner,
(person, pet) =>
new { OwnerName = person.Name, Pet = pet.Name });
这导致了@NetMage 的回答,成功的方法是:
// Build Queryable.Join<TOuter,TInner,TKey,TResult> and use as query expression
// IQueryable<TOuter>
var arg0 = Expression.Constant(people.AsQueryable());
// IEnumerable<TInner>
var arg1 = Expression.Constant(pets);
// TOuter person
var arg2p = Expression.Parameter(people.GetType().GetGenericArguments()[0], "person");
// also TKey person
// Expression<Func<TOuter,TKey>>: person => person
var arg2 = Expression.Quote(Expression.Lambda(arg2p, arg2p));
// TInner pet
var arg3p = Expression.Parameter(pets.GetType().GetGenericArguments()[0], "pet");
// TKey pet.Owner
var arg3body = Expression.Property(arg3p, "Owner");
// Expression<Func<TInner,TKey>>: pet => pet.Owner
var arg3 = Expression.Quote(Expression.Lambda(arg3body, arg3p));
// TResult = typeof(new { string OwnerName , string Pet })
var anonymousType = (new { OwnerName = default(string), Pet = default(string) }).GetType();
// .ctor
var arg4Constructor = anonymousType.GetConstructors()[0];
// person.Name
var arg4PersonName = Expression.Property(arg2p, "Name");
// pet.Name
var arg4PetName = Expression.Property(arg3p, "Name");
var arg4Args = new[] { arg4PersonName, arg4PetName };
// new[] { .OwnerName, .Pet }
var arg4Members = anonymousType.GetProperties();
// new { OwnerName = person.Name, Pet = pet.Name }
var arg4body = Expression.New(arg4Constructor, arg4Args, arg4Members);
// Expression<Func<TOuter,TInner,TResult>>: (person,pet) => new { OwnerName = person.Name, Pet = pet.Name }
var arg4 = Expression.Quote(Expression.Lambda(arg4body, arg2p, arg3p));
var joinGenericMI = typeof(Queryable).GetMethod("Join", 5);
var joinMI = joinGenericMI.MakeGenericMethod(new[] { arg2p.Type, arg3p.Type, arg2.ReturnType, anonymousType });
var qExpr = Expression.Call(joinMI, arg0, arg1, arg2, arg3, arg4);
对于此切片,需要更改前一个切片中出现的以下语句:
// TResult = typeof(new { string OwnerName , string Pet })
var anonymousType = (new { OwnerName = default(string), Pet = default(string) }).GetType();
@NetMage 将其改编为通用 A 和 B:
// TResult = typeof(new { A , B })
var anonymousType = (new { A = db.A.FirstOrDefault(), db.B = B.FirstOrDefault() }).GetType();
和
var arg4Constructor = anonymousType.GetConstructors()[0];
// person.Name
var arg4PersonName = Expression.Property(arg2p, "Name");
// pet.Name
var arg4PetName = Expression.Property(arg3p, "Name");
变成了(适用于通用 A 和 B):
// object A
var arg4A = arg2p;
// object B
var arg4B = arg3p;
现在需要通过b.Name和Selecta(下一个切片)过滤结果。
要从 Join
方法中获取 return 类型,请执行以下操作:
// TResult = typeof(new { A , B })
var anonymousType = (new { A = db.A.FirstOrDefault(), db.B = B.FirstOrDefault() }).GetType();
您需要创建一个匿名类型,其中成员 A
具有类型 db.A
实体类型。如果你使用例如typeof(A)
,那么你将得到 A
类型 Type
,与 Join
完全无关。 (如果您知道 A
的实体类型,您可以像我一样使用 default
:例如,如果 db.A
是 DbSet<AClass>
,则使用 A = default(AClass)
。)
由于您没有引用 Join
结果中的任何属性,您只需使用参数:
// object A
var arg4A = arg2p;
// object B
var arg4B = arg3p;