通用实体比较表达式构建器

时间:2016-02-03 13:55:54

标签: c# entity-framework linq entity-framework-6

如上所述here EntityFramework(至少在版本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与{的Id进行比较{1}}。

这样的事情:

RelationEntity

AreEquals将为正确生成的SQL调整表达式树,并在实体ID上进行比较。

我发现this post这似乎是一个良好的开端,但我无法将其附加到&#39; .Id&#39;表达的一部分。

我知道如何实现这一目标,或者可能是什么样的好方法?

1 个答案:

答案 0 :(得分:2)

你走了。

辅助函数(在一些静态类中):

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);
}