【问题标题】:Generic repository select by ID in EF4在 EF4 中按 ID 选择通用存储库
【发布时间】:2010-08-07 20:52:35
【问题描述】:

所以我正在尝试为基础存储库类创建一个通用的按 ID 选择方法。为了实现这一点,我将 EF4 与 POCO 一起使用。我用一个名为 Id 的 getter 创建了一个接口,并成功修改了 T4 模板,以便在所有返回 PK 的实体中都有一个通用的 Id 属性。

当我使用查询时,问题就来了。我是这样实现的:

public virtual T GetByID(int id)
{
    return Database.ObjectSet<T>().SingleOrDefault(entity => entity.Id == id);
}

即使 ObjectSet 返回的所有实体都使用其当前主键值设置了 Id 属性,但我收到了一个奇怪的错误:

指定的类型成员'Id'不是 在 LINQ to Entity 中支持。仅有的 初始化器、实体成员和 实体导航属性是 支持。

我错过了什么吗?

【问题讨论】:

    标签: c# entity-framework entity-framework-4


    【解决方案1】:

    如果仅通用 Id(如您所提)“返回 PK”但实际上并未映射到 PK 本身,则 EF 无法将其转换为 SQL 查询。

    我过去使用过的一种模式:如果您的所有实体都有一个名为 Id 的 int PK,那么您可以让它们都从定义(并映射到)该 Id 属性的某个基类继承,然后添加泛型方法的 where 子句:

    public virtual T GetByID(int id) where T : EntityBaseClass
    

    仅供参考,我还使用泛型将其用于具有不同类型 PK 的实体。

    【讨论】:

    • Id getter 返回 pk,它是映射实体的属性。 ObjectSet() 方法也具有以下签名。 public virtual IObjectSet ObjectSet() 其中 T :类,IEntity。其中 IEntity 是映射我所有实体的 PK 的接口。
    • 所以正如我所提到的,如果 ID 是一个返回 PK 的属性,但本身没有映射,那么 EF 应该如何知道如何使用它生成查询?就EF而言,这并没有映射到数据库,也无法查询!您需要查询映射的属性本身,解决方案是使用基类。或者,如果您映射实际的 ID 属性(而不是仅从 getter 返回 PK),那也可以。
    • 感谢您的评论和回答。
    • 另一种方法是为FirstOrDefault 方法提供Expression&lt;Func&lt;T, bool&gt;&gt; 参数并像repository.Get(e =&gt; e.Id == someId) 一样调用它。在这里查看我的实现:github.com/Necroskillz/NecroNetToolkit/blob/master/Source/….
    • 这不是我想要的。但这是一种有趣的方法。
    【解决方案2】:

    我不知道。我认为

    public virtual T GetByID(int id)
    

    这是个坏主意,因为它是硬编码。 如果我得到一个带有 guid 键的实体怎么办?

    STE 实体的矿山存储库

        public interface IRepository<TE, TK>
        where TE : class, IEntityId<TK>, new()
        where TK : struct
    {
        IQueryable<TE> Query();
        IQueryable<TE> Query(Expression<Func<TE, Object>> includeExpression);
        IQueryable<TE> Query(IEnumerable<Expression<Func<TE, Object>>> includeExpressions);
    
        TE GetById(Expression<Func<TE, Boolean>> predicate);
        void Create(TE entity);
        void Update(TE entity);
        void Delete(TE entity);
    }
    
        public interface IEntityId<out TK> where TK : struct
    {
        TK Id { get; }
        Int32 OwnerCode { get; }
    }
    

    【讨论】:

    • 如果你要提供一个表达式,那么我看不到 IEntityId 接口中的值 - 我错过了什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-16
    • 2017-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多