【问题标题】:Entity Framework Simple Generic GetByID but has differents PK Name实体框架简单的通用 GetByID 但具有不同的 PK 名称
【发布时间】:2011-07-13 12:07:09
【问题描述】:

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

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

谢谢。

【问题讨论】:

    标签: entity-framework-4


    【解决方案1】:

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

    https://msdn.microsoft.com/en-us/library/dn246936(v=vs.113).aspx

    【讨论】:

      【解决方案2】:

      这是为具有单个属性键的实体构建的存储库的基本存储库类示例。 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
          }
      }
      

      使用此代码时有一个小问题。如果您不使用从ObjectContext 派生的生成类而直接使用ObjectContext,则必须手动设置模型使用的DefaultContainerName

      编辑:

      此方法适用于经典 EF。如果需要,我可以考虑 Code-first 的版本。

      【讨论】:

      • @Jean-Francois:只需提取构建泛型方法所需的代码即可。我这样写是为了减少搜索实体集名称和键名的次数。基础是:如果你想要通用的“GetByKey”,你必须在元数据中找到键。
      • @LadislavMrnka - 如果实体尚未保存到数据库但只是在本地插入,则此方法不起作用 - GetObjectByKey 表示即使我调用 oc.ObjectStateManager 也找不到具有该键的实体。 GetObjectStateEntries(EntityState.Added | EntityState.Modified) 我看到该实体有一个对象状态条目。
      • @Bond:是的,它不适用于非持久化实体,因为它们还没有真正的密钥。如果您想获得它们,您必须使用 GetObjectStateEntries 并为您的实体搜索结果集。
      • @LadislavMrnka - 是的,这正是我想要做的,但我想以一种通用的方式搜索它们。我尝试了 oc.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Deleted).Where(e => e.EntityKey.Equals(entityKey)) 但无济于事,添加的(但尚未保存)实体的 EntityKey 显示 EntityKeyValues : null, IsTemporary: true 我猜这会使搜索失败。我的密钥不是自动生成的(它们是字符串)。
      • @Bond:它们是否自动生成并不重要。如果您的实体处于添加状态,它只有临时密钥,因为您仍然可以更改它(同时不允许更改现有实体的密钥)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-14
      • 2011-05-31
      • 1970-01-01
      • 1970-01-01
      • 2014-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多