动态 LINQ IQueryable(在运行时生成表达式)

Dynamic LINQ IQueryable (Generate Expression at runtime)

我有以下查询

query.Join(
    relationEntity,
    entity => new { Prop1 = EF.Property<object>(entity, "Id"), Prop2 = Ef.Property...},
    relation => new { Prop1 = EF.Property<object>(relation, "EntityId"), Prop2 = EF.Property... },
    (Entity, Relation) => new { Entity, Relation })

我需要在运行时生成密钥。如何实现?我已经尝试在运行时构建一个表达式,但它看起来像 Join 从字面上获取接收到的值,所以如果我在那里调用一个方法,它会被转换为该方法名称而不是结果。

我正在用 atm 测试的方法:

   private static object MyMethod(object entity, string name)
             => new { Id = EF.Property<object>(entity, name) };



   query.Join(
        relationEntity,
        entity => MyMethod(entity, "Id"),
        relation => MyMethod(relation, "EntityId"),
        (Entity, Relation) => new { Entity, Relation })

要使您的 MyMethod 成为表达式,您必须像这样处理它

private static Expression<Func<T, object>> MyMethod<T>(string name) => 
         (T entity) => new { Id = EF.Property<object>(entity, name) };

query.Join(
    relationEntity,
    MyMethod<entityType>("Id"),
    MyMethod<relationType>("EntityId"),
    (Entity, Relation) => new { Entity, Relation })

该方法必须 return 一个表达式,而不是任何计算结果。

但是您的 MyMethod 越复杂,您就越不可能将其转换为 SQL。

这里更多的是为了让您的代码更短、更易读。那里还没有动态。

这样的事情不是问题,因为这个选择是在 SQL-Creation 之前执行的。

private static Expression<Func<T, object>> MyMethod<T>(string name) 
{ 
    if (case 1)
         return (T entity) => new { Id = EF.Property<object>(entity, name) };
    if (case 2) 
         return (T entity) => new { Id = EF.Property<object>(entity, name), Id2 = ... something else }
}