通用实体比较表达式生成器



正如这里所说,实体框架(至少在版本6中(不支持用户类型比较(因此,实体比较(,这对于ORM来说是不切实际的。

有一个场景,其中我有很多代码可以进行实体比较,这些代码应该转换为SQL。
我的所有实体都有一个 int 类型的 Id 字段。

class Entity
{
    public int Id { get; set; }
}

对于我想比较 Where 子句中的实体的查询,我希望编译器能够检测是否尝试执行无效的比较。

考虑以下类:

class SomeEntity : Entity
{
    public RelationEntity_Id int{ get; set; }
    public RelationEntity Relation { get; set; }
}
class RelationEntity : Entity
{
}

使用以下语法,可以对类型进行此类检查:

public IQueryable<SomeEntity> SearchByRelation(RelationEntity relation)
{
    return CreateQueryable().Where(e => s.Relation == relation);
}

对于下面的,我们只是比较int,这可能容易出错:

public IQueryable<SomeEntity> SearchByRelation(RelationEntity relation)
{
    return CreateQueryable().Where(e => s.Relation.Id == relation.Id);
}

因为需要告诉 EntityFramework 应该如何对对象进行比较,所以我正在寻找一种方法来创建返回表达式的通用表达式 比较SomeEntity的 Id 与RelationEntity的 Id 。

像这样:

public IQueryable<SomeEntity> SearchByRelation(RelationEntity relation)
{
    return CreateQueryable().Where(e => AreEquals(s.Relation, relation));
}

AreEquals 将调整表达式树,以正确生成比较实体 ID 的 SQL。

我发现这篇文章似乎是一个好的开始,但我无法让它附加".表达式的 Id' 部分。

关于我如何实现这一目标的任何想法,或者有什么好方法?

你去吧。

辅助函数(在某个静态类中(:

public static IQueryable<T> WhereEquals<T>(this IQueryable<T> source, T target)
    where T : Entity
{
    var item = Expression.Parameter(typeof(T), "item");
    var body = Expression.Equal(
        Expression.Property(item, "Id"),
        Expression.Property(Expression.Constant(target), "Id"));
    var predicate = Expression.Lambda<Func<T, bool>>(body, item);
    return source.Where(predicate);
}

和用法:

public IQueryable<SomeEntity> SearchByRelation(RelationEntity relation)
{
    return CreateQueryable().WhereEquals(relation);
}

最新更新