如何使用Entity Framework 4和存储库模式实现通用的GetById方法?

时间:2011-04-03 03:10:12

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

我有一个通用存储库,想要实现一个通用的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);
}

我正在使用Entity Framework 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;

感谢。

2 个答案:

答案 0 :(得分:5)

从这个问题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;

    }

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

答案 1 :(得分:0)

对于那些“幸运”足够在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