EF6可以根据映射的数据库类型的主键自动检查对象吗?

时间:2016-07-18 16:14:20

标签: entity-framework generics ef-code-first entity-framework-6

我有一个通用方法,当外部源向我发送一个对象时,该方法会持久保存到我想要像这样工作的数据库...

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))

1 个答案:

答案 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);

我不知道第一部分的效率如何,但显然可以在一定程度上缓存它。