Entity framework 4 实体框架简单的泛型GetByID,但具有不同的PK名称

Entity framework 4 实体框架简单的泛型GetByID,但具有不同的PK名称,entity-framework-4,Entity Framework 4,有人可以帮我创建一个通用的GetByID方法, 这里的挑战是,我有很多实体,每个实体都有不同的PK名称 我看到了几个具有通用GetByID的示例,但其中许多都有相同的PK名称,如(id) 谢谢。这里是为具有单个属性键的实体构建存储库的基本存储库类的示例。GetByKey方法独立于键名或键类型 using System; using System.Data; using System.Data.Metadata.Edm; using System.Data.Objects; using Syste

有人可以帮我创建一个通用的GetByID方法, 这里的挑战是,我有很多实体,每个实体都有不同的PK名称

我看到了几个具有通用GetByID的示例,但其中许多都有相同的PK名称,如(id)


谢谢。

这里是为具有单个属性键的实体构建存储库的基本存储库类的示例。
GetByKey
方法独立于键名或键类型

using System;
using System.Data;
using System.Data.Metadata.Edm;
using System.Data.Objects;
using System.Linq;

namespace EntityKeyTest
{
    // Base repository class for entity with simple key
    public abstract class RepositoryBase<TEntity, TKey> where TEntity : class
    {
        private readonly string _entitySetName;
        private readonly string _keyName;

        protected ObjectContext Context { get; private set; }
        protected ObjectSet<TEntity> ObjectSet { get; private set; }

        protected RepositoryBase(ObjectContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            Context = context;
            ObjectSet = context.CreateObjectSet<TEntity>();

            // Get entity set for current entity type
            var entitySet = ObjectSet.EntitySet;
            // Build full name of entity set for current entity type
            _entitySetName = context.DefaultContainerName + "." + entitySet.Name;
            // Get name of the entity's key property
            _keyName = entitySet.ElementType.KeyMembers.Single().Name;
        }

        public virtual TEntity GetByKey(TKey key)
        {
            // Build entity key
            var entityKey = new EntityKey(_entitySetName, _keyName, key);
            // Query first current state manager and if entity is not found query database!!!
            return (TEntity)Context.GetObjectByKey(entityKey);
        }

        // Rest of repository implementation
    }
}
使用系统;
使用系统数据;
使用System.Data.Metadata.Edm;
使用System.Data.Object;
使用System.Linq;
命名空间EntityKeyTest
{
//具有简单密钥的实体的基本存储库类
公共抽象类RepositoryBase,其中tenty:class
{
私有只读字符串_entitySetName;
私有只读字符串_keyName;
受保护的ObjectContext上下文{get;private set;}
受保护的对象集对象集{get;private set;}
受保护的RepositoryBase(ObjectContext上下文)
{
if(上下文==null)
{
抛出新的ArgumentNullException(“上下文”);
}
上下文=上下文;
ObjectSet=context.CreateObjectSet();
//获取当前实体类型的实体集
var entitySet=ObjectSet.entitySet;
//为当前实体类型生成实体集的全名
_entitySetName=context.DefaultContainerName+“+entitySet.Name;
//获取实体的键属性的名称
_keyName=entitySet.ElementType.KeyMembers.Single().Name;
}
公共虚拟密钥GetByKey(TKey)
{
//生成实体密钥
var entityKey=new entityKey(_entitySetName,_keyName,key);
//查询第一个当前状态管理器,若找不到实体,则查询数据库!!!
return(TEntity)Context.GetObjectByKey(entityKey);
}
//存储库实现的其余部分
}
}
使用此代码时有一个涓涓细流。如果您不使用从
ObjectContext
派生的生成类,并且直接使用
ObjectContext
,则必须手动设置模型使用的
DefaultContainerName

编辑:


此方法适用于经典EF。如果需要的话,我可以先考虑代码的版本。

我知道这个答案很旧,专门标记为EF-4,但从EF-6 fwiw开始,Find()或FindAsync()是正确的解决方案:


@Jean Francois:只需提取构建泛型方法所需的代码即可。我这样写是为了减少搜索实体集名称和键名称的次数。其基础是:如果要使用通用的“GetByKey”,则必须在元数据中找到该键。@LadislavMrnka-如果实体尚未保存到数据库,但只是在本地插入,则此操作无效-GetObjectByKey表示,即使在调用oc.ObjectStateManager.GetObjectStateEntries时,它也无法找到具有该键的实体(EntityState.Added | EntityState.Modified)我看到该实体有一个对象状态项。@邦德:是的,它不适用于未持久化的实体,因为它们还没有真正的键。如果要获取它们,必须使用
GetObjectStateEntries
和实体的搜索结果集。@LadislavMrnka-是的,这正是我要做的,但我想在我尝试了oc.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Deleted)。其中(e=>e.EntityKey.Equals(EntityKey)),但没有效果,添加(但尚未保存)实体的EntityKey显示EntityKeyValues:null,IsTemporary:true,我想这会导致搜索失败。我的键不是自动生成的(它们是字符串)。@Bond:它们是否自动生成并不重要。如果您的实体处于添加状态,它只有临时密钥,因为您仍然可以更改它(但不允许更改现有实体的密钥)。