我有一个存储库层,我的应用程序可以使用
IDataSource
;例如linqtosqldatasource、entityframeworkdatasource等…
IDataSource分别提供插入、更新、删除和查询数据源的方法。与这个问题相关的是
FindAll<T>
返回一个
IQueryable<T>
.
我的所有基本实体都实现了一个简单的接口,使按id查找实体通用方便;
public interface IAmIdentifiable<T>
{
T Id { get; set; }
}
下面是
FindById<T, TKey>
方法我在实体框架中遇到问题。
public class Repository
{
public Repository(IDataSource dataSource)
{...}
public T FindById<T, TKey>(TKey identifier) where T : class, IAmIdentifiable<TKey>
{
return _DataSource.FindAll<T>().SingleOrDefault(i => i.Id.Equals(identifier));
}
...
}
这个
FindById<T, Tkey>(...)
可以与linqtosql一起使用,但不能在entityframework 4中使用
.
示例用法
User user = Repository.FindById<User, int>(someUserId);
Message msg = Repository.FindById<Message, Guid>(someMessageId);
当上面的代码与EntityFramework4IDataSource实现一起运行时,会产生以下错误:
无法创建“system.object”类型的常量值。在此上下文中仅支持基元类型(如int32、string和guid)。
我已经尝试更改此项以对值类型执行一个==比较。我了解到,将泛型约束到值类型的迂回方法是
struct
. 我已经更新了所有实体的基本接口和相应的存储库查找程序…
public interface IAmIdentifiable<T> where T : struct
{
T Id { get; set; }
}
public T FindById<T, TKey>(TKey identifier)
where T : class, IAmIdentifiable<TKey>
where TKey : struct
{
return _DataSource.FindAll<T>().SingleOrDefault(i => i.Id == identifier);
}
但是这仍然会导致编译错误;
错误59运算符“==”不能应用于“tkey”和“tkey”类型的操作数
有谁能解释一下我如何把这些实体
IAmIdentifiable<T>
接口,以便具有按ID检索实体的通用方法?