动态设置要在LINQ查询中加入的实体

我有一个查询:

from joinedEntity in joinedEntities join relatedEntity in dbContext.X on .... 

现在,我想以“X”可以动态传递的方式编写上述查询,这样我就不需要为每个不同的“X”编写单独的linq查询。 有帮助吗? 我应该使用表达树和reflection吗? 如果有,怎么样? 谢谢。

我有一些猜测它应该是这样的:

 var parameter = Expression.Parameter(typeof (CompanyContext), "dbContext"); var member = Expression.MakeMemberAccess(parameter, typeof(CompanyContext).GetMember("X")[0]); ..... 

以下是我的加入示例:

  from joinedEntity in joinedEntities join relatedEntity in dbContext.Channels on joinedEntity.Id equals relatedEntity.CId select new JoinedEntities(joinedEntity) { Channel = relatedEntity.Name }; 

这是它的方法语法:

 joinedEntities.Join(dbContext.Channels, m => m.Id, k => k.CId, (m, k) => new JoinedEntities(m) { Channel = k.Name }); 

这也是另一个:

 from joinedEntity in joinedEntities join relatedEntity in dbContext.ActivityOutput on joinedEntity.Id equals relatedEntity.CId select new JoinedEntities(joinedEntity) { ActivityOutput = relatedEntity.Name }; 

最简单的方法是创建一个表示存在CId字段的界面。

 // Don't know if you need this one or if you want to have the class of joinedEntities always being the same public interface IJoinedEntities { int Id { get; set; } } public interface IRelatedEntity { int CId { get; set; } } 

所有相关实体都需要实现IRelatedEntity。 entity framework的所有类都是部分的,因此您只需要创建另一个部分类来添加此接口。

由于您希望投影只是创建一个扩展方法,我们将链接到标准连接。

 public static class CustomIQueryableExtensions { public static IQueryable CommonJoinQueryable(this IQueryable outer, IQueryable inner, Expression> resultSelector) where TOuter : IJoinedEntities where TInner : IRelatedEntity { // have to use expression trees to build the join otherwise cast to interface is in expression tree var outerParam = Expression.Parameter(typeof (TOuter), "outer"); var outerBody = Expression.Lambda>(Expression.Property(outerParam, "CId"), outerParam); var innerParam = Expression.Parameter(typeof (TInner), "inner"); var innerBody = Expression.Lambda>(Expression.Property(innerParam, "Id"), innerParam); return outer.Join(inner, outerBody, innerBody, resultSelector); } public static IEnumerable CommonJoinEnumerable(this IEnumerable outer, IEnumerable inner, Func resultSelector) where TOuter : IJoinedEntities where TInner : IRelatedEntity { // have to use expression trees to build the join otherwise cast to interface is in expression tree Func outerJoin = outerParam => outerParam.Id; Func relatedJoin = innerParam => innerParam.CId; return outer.Join(inner, outerJoin, relatedJoin, resultSelector); } } 

现在你可以使用它并仍然处理投影。

 joinedEntities.CommonJoinQueryable(dbContext.Channels, (m, k) => new JoinedEntities() { Channel = k.Name, tracking = m }); joinedEntities.CommonJoinEnumerable(dbContext.Channels, (m, k) => new JoinedEntities(m) { Channel = k.Name }); 

您仍然应该使用SQL事件探查器来查看使用Enumerable时生成的内容,因为它会将结果拉下来,然后将它们连接到内存中,而不是SQL中。 我知道这就是你的要求,但这并不常见。 您不应该将参数传递给构造函数,而应该考虑创建一个可以使用投影设置的属性,然后使用IQueryable。

我相信这是lnanikian试图得到的。