我有一个通用存储库,想要实现一个通用的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;
感谢。
答案 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