Entity framework 如何使用EntityFramework4和Repository模式实现通用的GetById方法?

Entity framework 如何使用EntityFramework4和Repository模式实现通用的GetById方法?,entity-framework,entity-framework-4,repository-pattern,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>&g

我有一个通用存储库,希望实现一个通用的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);
}
但是,当尝试使用该方法时,我收到一个异常:

指定的类型成员“EntityKey”在LINQ to实体中不受支持。仅支持初始值设定项、实体成员和实体导航属性。

有人能告诉我怎么才能让它工作吗

更新1

成员_objectContext和_context声明如下:

private readonly ObjectContext _context;
private readonly IObjectSet<T> _objectSet;
private readonly ObjectContext\u context;
私有只读IObjectSet\u对象集;
谢谢。

通过这个问题,您可以稍微作弊一下,然后使用ESQL

    public T GetById(int id)
    {

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

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

    }
我已经在方法中包含了所有需要的代码,显然您希望对其进行一点重构,但它应该适合您。

对于那些“幸运”能够在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
导入System.Runtime.CompilerServices
导入System.Data.Object
导入System.Collections.Generic
公共模块ObjectSetExtension
公共函数GetById(属于T类)(self-As-ObjectSet(属于T类),Id为整数)
Dim keyPropertyName=self.EntitySet.ElementType.KeyMembers(0).ToString()
作为T=self.Where(“it.”&keyPropertyName&“=”&Id)的Dim实体。第一个
返回实体
端函数
公共函数GetById(属于T类)(self-As-ObjectSet(属于T类),Id-As-Guid)
Dim keyPropertyName=self.EntitySet.ElementType.KeyMembers(0).ToString()
“”请注意字符串中的“GUID”。不要移除!
作为T=self.Where(“it.”&keyPropertyName&“=GUID'&Id.ToString()&“”)的Dim实体。首先
返回实体
端函数
端模块

我在上面添加了一些信息,因为我的ObjectSet不公开属性上下文或EntitySet。不过,将IOObjectSet更改为ObjectSet成功了。如果它以后能工作,我们会发布。如果我们不知道确切的id数据类型呢。它可以是int、Int16、Int64、long等等。动态地将其转换为实体的Id数据类型的最佳方法是什么?我们实际上只是将其用作字符串,因此您可以将Id类型更改为任何类型,只要ToString()方法能够准确地反映值,你应该保持良好的状态。检查这个答案:它正好包含你想要的东西。
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