代码之家  ›  专栏  ›  技术社区  ›  e36M3

如何获取自跟踪实体的主键?

  •  5
  • e36M3  · 技术社区  · 15 年前

    public T GetByID(int id)
    {
        return (T) context.GetObjectByKey(
            new System.Data.EntityKey(context.DefaultContainerName + "." +
                 context.CreateObjectSet<T>().EntitySet.Name, 
                 "ProductID", id));
    }
    

    基本上我可以从T中推断实体名,但是我不知道如何找出实体的主键是什么?

    3 回复  |  直到 15 年前
        1
  •  5
  •   jerone    12 年前

    最后,我创建了自己的属性并修改了T4模板,将该属性放在主键列的上方。以下是我采取的步骤:

    1. <#if (ef.IsKey(edmProperty)) {#>    
      [PrimaryKeyAttribute]
      <#}#>
      
    2. 创建PrimaryKeyAttribute:

      [AttributeUsage(AttributeTargets.Property)]
      public class PrimaryKeyAttribute : Attribute
      {}
      
    3. private string GetPrimaryKey<K>()
      {
          string primaryKey = string.Empty;
      
          PropertyInfo[] entityProperties = typeof(K).GetProperties();
      
          foreach (PropertyInfo prop in entityProperties)
          {
              object[] attrs = prop.GetCustomAttributes(false);
              foreach (object obj in attrs)
              {
                  if (obj.GetType() == typeof(PrimaryKeyAttribute))
                  {
                      primaryKey = prop.Name;
                      break;
                  }
              }
          }
      
          if (string.IsNullOrEmpty(primaryKey))
              throw new Exception("Cannot determine entity's primary key");
      
          return primaryKey;
      }
      
    4. public T GetByID(int id)
      {
          return (T)context.GetObjectByKey(new EntityKey(context.DefaultContainerName 
                                              + "." + context.CreateObjectSet<T>().EntitySet.Name
                                              , GetPrimaryKey<T>(), id));            
      }
      
        2
  •  3
  •   itchi    15 年前

        _qualifiedTypeName = _context.DefaultContainerName + "." + _baseTypeName;
        Type baseType = GetBaseType(typeof(T));
        _baseTypeName = baseType.Name.ToString();
    
        PropertyInfo[] entityProperties = baseType.GetProperties();
        List<string> keyList = new List<string>();
    
        foreach (PropertyInfo prop in entityProperties) 
        {
          object[] attrs = prop.GetCustomAttributes(false);
          foreach (object obj in attrs)                
          {
            if (obj.GetType() == typeof(EdmScalarPropertyAttribute))
            {
              EdmScalarPropertyAttribute attr = (EdmScalarPropertyAttribute)obj;
              if (attr.EntityKeyProperty) keyList.Add(prop.Name);
             }
           }
        }
        if (keyList.Count > 0)
        {
          _keyName = keyList[0];
        }
    

    然后你会像这样归还它:

    EntityKey key = new EntityKey(_qualifiedTypeName, _keyName, id);
    return (T)_context.GetObjectByKey(key);
    

    看起来我从这里得到了上面的信息: http://blog.vascooliveira.com/how-to-check-for-an-entity-objects-entitykey-properties/

        3
  •  3
  •   Ryan Wilson    14 年前
    Here's another solution that uses the MetadataWorkspace...
    
    1. Create a base DataAccess class with the following signature.
    
            public class DataAccessBase<TDataEntity> : IDisposable
                where TDataEntity : EntityObject
    
    2. Create a method in DataAccessBase as the following...
    
    
        public TDataEntity GetByKey(object keyId)
                {
                    // Get the entity key name
                    var keyName = EntityContext.MetadataWorkspace
                                    .GetEntityContainer(EntityContext.DefaultContainerName, DataSpace.CSpace)
                                    .BaseEntitySets
                                    .First(x => x.ElementType.Name == typeof(TDataEntity).Name)
                                    .ElementType
                                    .KeyMembers
                                    .Select(key => key.Name)
                                    .FirstOrDefault();
    
                    // Get the Entity Set name
                    var entitySet = (from container in EntityContext.MetadataWorkspace.GetItems<EntityContainer>(DataSpace.CSpace)
                                     from set in container.BaseEntitySets.OfType<EntitySet>()
                                     where set.ElementType.Name == typeof(TDataEntity).Name
                                     select set).FirstOrDefault();
    
    
                    // Create qualified type name for entity
                    string qualifiedTypeName = String.Format("{0}.{1}", EntityContext.DefaultContainerName, entitySet.Name);
    
                    // Create the EntityKey
                    EntityKey entityKey = new EntityKey(qualifiedTypeName, keyName, keyId);
    
                    // Return object by it's entity key
                    return (TDataEntity)EntityContext.GetObjectByKey(entityKey);
                }