【问题标题】:How to implement a generic GetById method using Entity Framework 4 and the Repository Pattern?如何使用实体框架 4 和存储库模式实现通用 GetById 方法?
【发布时间】:2014-02-19 15:46:32
【问题描述】:

我有一个通用存储库,并希望实现一个通用 GetById 方法。到目前为止,这是我的存储库界面:

public interface IRepository<T> where T : EntityObject  
{
    void Add(T entity);
    void Delete(int id);
    void Delete(T entity);
    IEnumerable<T> Find(Expression<Func<T, bool>> predicate);
    T SingleOrDefault(Expression<Func<T, bool>> predicate);
    IEnumerable<T> GetAll();
    T GetById(int id);
    void Save();
    T Single(Expression<Func<T, bool>> predicate);
}

我正在使用实体框架 4.1。我发现的许多解决方案都是为 IEntity 类使用接口的抽象基类,实体必须从该类继承才能执行 Id 查找。

我试图使用这段代码,而不是为我的所有类实现一个接口:

T entity = _objectSet.Where(
    x => x.EntityKey.EntityKeyValues
          .Select(v => v.Value.Equals(id)).Count() == 1).First();

但是,当我尝试使用该方法时,我收到了异常:

The specified type member 'EntityKey' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.

有人能告诉我如何让它工作吗?

更新 1

成员 _objectContext 和 _context 声明如下:

private readonly ObjectContext _context;
private readonly IObjectSet<T> _objectSet;

谢谢。

【问题讨论】:

标签: entity-framework entity-framework-4 repository-pattern


【解决方案1】:

从这个问题How to get ObjectSet<T>'s entity key name?,你可以稍微作弊,使用ESQL。

    public T GetById(int id)
    {

        var keyPropertyName = _objectSet.EntitySet.ElementType.KeyMembers[0].ToString();        

        T entity = _objectSet.Where("it." + keyPropertyName + "=" + id).First();
        return entity;

    }

我已经在方法中包含了所有需要的代码,显然你想稍微重构一下,但它应该适合你。

【讨论】:

  • 我在上面添加了一些信息,因为我的 ObjectSet 没有公开属性 Context 或 EntitySet。
  • 没关系,将 IObjectSet 更改为 ObjectSet 就可以了。如果它以后工作将发布。
  • 如果我们不确切知道 id 数据类型怎么办。它可以是 int、Int16、Int64、long 等。将其动态转换为实体的 Id 数据类型的最佳方法是什么?
  • 我们这里实际上只是将其用作字符串,因此您可以将 id 类型更改为任何类型,只要 ToString() 方法能够准确反映该值,您应该处于良好状态。
【解决方案2】:

对于那些“幸运”地在 VB.net 中工作并且您正在努力获得一个工作示例的人:

Imports System.Runtime.CompilerServices
Imports System.Data.Objects
Imports System.Collections.Generic

Public Module ObjectSetExtension

    <Extension()>
    Public Function GetById(Of T As Class)(self As ObjectSet(Of T), Id As Integer)
        Dim keyPropertyName = self.EntitySet.ElementType.KeyMembers(0).ToString()
        Dim entity As T = self.Where("it." & keyPropertyName & "=" & Id).First
        Return entity
    End Function

    <Extension()>
    Public Function GetById(Of T As Class)(self As ObjectSet(Of T), Id As Guid)
        Dim keyPropertyName = self.EntitySet.ElementType.KeyMembers(0).ToString()
        ' 'note the "GUID" in the string. DO NOT REMOVE!
        Dim entity As T = self.Where("it." & keyPropertyName & "=GUID '" & Id.ToString() & "'").First
        Return entity
    End Function

End Module

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-11
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多