我有一个通用方法,当外部源向我发送一个对象时,该方法会持久保存到我想要像这样工作的数据库...
public void PersistToDB<T>(T object)
{
using(var dbContext = ...)
{
//if(dbContext.Set<T>.Any(x => x.PrimaryKeyMatches(object))...
}
}
我没有将这些对象保存在内存中,只需保存它们 - INSERT或UPDATE。我的问题是,虽然我可以dbContext.Set<T>.Any(x => x.id == object.id)
或dbContext.Set<T>.Find(object.id)
来查找对象是否存在,但我必须知道要搜索的字段。 EF肯定知道哪些字段定义了T
的PK,所以我希望我可以通过它object
它会自动为我做这件事,或者为我提供一个我可以传递给Any
的代表,但我怎么看不到?
调用dbContext.Entry(object)
不,据我所知,做我想要的...它会告诉我指定的对象处于Detached
状态,因为没有本地复制举行。
有没有办法可以做我想做的事情,而不必编写破坏我整洁的通用实现的类型特定代码?
编辑:基于Generic Way to Check If Entity Exists In Entity Framework?中的内容我认为其中很多内容都已涵盖在内。我真正想要的是一种围绕该代码创建委托/行动func
的方法,然后我可以将其传递给Any(x => func(x))
答案 0 :(得分:0)
要回答我自己的问题,这就是我最终要做的事情。虽然我可以根据类型自动生成PK,但我无法看到一种动态生成lambda表达式的方法。所以我不得不走Find
路线,而不是Any
路线,它确实存在从DB中拉出每个物体的轻微问题。但是,这确实意味着只有实际更改的列才会在现有对象上更新,我认为这至少可以部分地减轻这一点。
using(var dbContext = ...)
{
var objectContext = ((IObjectContextAdapter)dbContext).ObjectContext;
var objectSet = objectContext.CreateObjectSet<T>();
string entitySetName = objectSet.EntitySet.Name;
//find the PK columns and values for this type and instance
var entityKey = objectContext.CreateEntityKey(entitySetName, item);
var pk = entityKey.EntityKeyValues.Select(_ => _.Value).ToArray();
var entity = dbContext.Set<T>().Find(pk);
我不知道第一部分的效率如何,但显然可以在一定程度上缓存它。