如何通过取景器界面中查找4的EntityFramework实体? (在LinqToSql作品) [英] How to lookup entities in EntityFramework 4 by a finder interface? (works in LinqToSql)
问题描述
我有一个存储库层,我的应用程序的访问可与被初始化的的IDataSource
;例如LinqToSqlDataSource,EntityFrameworkDataSource,等等...
这是提供的IDataSource插入,更新,删除和查询各自的数据源的方法。有关这个问题,就是的FindAll< T>
返回的IQueryable< T>
我所有的基本实体实现一个简单的界面,使通过ID通用,方便查找实体;
公共接口IAmIdentifiable< T>
{$ B $(B T)标识{搞定;组; }
}
下面是相关代码的 FindById< T,TKEY的方式>
方法我有在的EntityFramework问题
公共类资源库
{
公共库(的IDataSource数据源)
{...}
公共牛逼FindById< T,TKEY的>(TKEY的标识符)其中T:类,IAmIdentifiable< TKEY的>
{
返回_DataSource.FindAll< T>()的SingleOrDefault(I => i.Id.Equals(标识));
}
:
}
这 FindById< T,TKEY>(...)
正常工作与LinqToSql但在的EntityFramework 4
$ b
示例使用
用户的用户= Repository.FindById<使用者,INT>(someUserId);
信息味精= Repository.FindById<消息中GUID>(someMessageId);
在上面的代码与它产生以下错误的的EntityFramework 4的IDataSource实现上运行;
无法创建类型的常值'System.Object的。只有原始类型('如的Int32,字符串和GUID')在这方面的支持。
我试图改变这个来执行==比较价值类型。我读来约束一个通用的值类型一种迂回的方式就是要约束结构
。我已经更新了所有实体的基本接口和相应的库取景器...
公共接口IAmIdentifiable< T>其中T:结构
{$ B $(B T)标识{搞定;组; }
}
公共牛逼FindById< T,TKEY的>(TKEY的标识符)
,其中T:类,IAmIdentifiable< TKEY的>
式TKEY的:结构
{
返回_DataSource.FindAll< T>()的SingleOrDefault(I => i.Id ==标识符);
}
但是这仍然会导致编译错误;
错误59运算符'=='不能应用于类型为TKEY的'和'TKEY的
<操作数p >任何人都可以阐明我怎么会去投这些实体的一些光
IAmIdentifiable< T>为了有一个通用的方法按ID检索实体
接口 不要问我为什么这个作品,但我们设法让做这一点:
I => (对象)i.Id ==(对象)标识符
不知怎的,这很好地表现,并写入正确的SQL WHERE
条款。所有我们尝试没有工作的其他替代品。
I have a repository layer which my applications access which can be initialised with an IDataSource
; e.g. LinqToSqlDataSource, EntityFrameworkDataSource, etc...
An IDataSource provides methods for inserting, updating, deleting and querying a data source respectively. Relevant to this question, is that the FindAll<T>
returns an IQueryable<T>
.
All my base entities implement a simple interface to make looking up entities by id generic and convenient;
public interface IAmIdentifiable<T>
{
T Id { get; set; }
}
Below is the relevant code for the FindById<T, TKey>
method I am having problems with in EntityFramework.
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));
}
...
}
This FindById<T, Tkey>(...)
works fine with LinqToSql but does not work in EntityFramework 4.
Example usage
User user = Repository.FindById<User, int>(someUserId);
Message msg = Repository.FindById<Message, Guid>(someMessageId);
When the above code is run with an EntityFramework 4 IDataSource implementation it produces the following error;
Unable to create a constant value of type 'System.Object'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.
I have tried changing this to perform an == comparison on value types. I read that a roundabout way to constrain a generic to a value type is to constraint to struct
. I have updated the base interface for all entities and the repository finder accordingly...
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);
}
However this still results in a compilation error;
Error 59 Operator '==' cannot be applied to operands of type 'TKey' and 'TKey'
Can anybody shed some light on how I might go about casting these entities to the IAmIdentifiable<T>
interface in order to have a generic way to retrieve entities by Id?
Don't ask me why this works, but we managed to make this happen by doing:
i => (object)i.Id == (object)identifier
Somehow this behaves nicely and writes the correct SQL WHERE
clause. All of the other alternatives we tried didn't work.
这篇关于如何通过取景器界面中查找4的EntityFramework实体? (在LinqToSql作品)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!