2014-10-08 60 views
0

我想弄清楚如何将属性设置为主键。我的意思是,我有一个POCO对象我试图定义一个键是这样的:将属性设置为主键

public class POCO 
{ 
    [PrimaryKey] 
    int Id; 

    string Name; 
    int Age;  
} 

然后我试图访问它像这样:

public static object ReturnKeyValue(this POCO poco) 
{ 
    return poco.[PrimaryKey]; //should return Id 
} 

我是什么在这里做错了吗?

+0

[关键]如果你谈论的是EF数据注解,请更具体 – InferOn 2014-10-08 06:15:15

+0

我说的是从任何地方我使用的是类标识键属性。 – RealWorldCoder 2014-10-08 06:16:24

+0

这些类只是运营商,不需要知道有关数据库的任何信息。 – elvin 2014-10-08 06:18:42

回答

1

POCO类的PrimaryKey属性可以通过getter和setter来公开吗?

public class POCO 
{ 
    [PrimaryKey] 
    public int Id { get; set; } 

    string Name; 
    int Age; 
} 

如果是这样,那么下面的扩展方法应该返回任何给定的POCO实例的PrimaryKey字段的值。

public static object ReturnKeyValue(this POCO poco) 
{ 
    return (from p in poco.GetType().GetProperties() 
      let attr = p.GetCustomAttributes(typeof(PrimaryKeyAttribute), true) 
      where attr.Length == 1 
      select p).First().GetValue(poco, null); 
} 
0

我有类似的东西,昨天我发现了一个解决方案,所以我很乐意分享它。 您需要知道的一点是,当您有组合键时,您尝试执行的操作将无法工作,这意味着拥有一个POCO对象,该对象具有一个主键,该主键可以从多个单个元素中进行选择。

比方说,我有下面的类(POCO):

public class Person : EntityBase<int> 
{ 
    #region Properties 

    /// <summary> 
    ///  Gets or sets the id of the entity. 
    /// </summary> 
    [Key] 
    public TKey Id { get; set; } 

    /// <summary> 
    ///  Gets or sets the name. 
    /// </summary> 
    public string Name { get; set; } 

    /// <summary> 
    ///  Gets or sets the firstname. 
    /// </summary> 
    public string FirstName { get; set; } 

    /// <summary> 
    ///  Gets or sets the <see cref="Manager"/>. 
    /// </summary> 
    public Manager Manager { get; set; } 

    #endregion 
} 

我在这里使用实体框架,因此定义主键的属性称为Key而不是PrimaryKey在你的榜样。

现在,我确实有类作为存储库。这个类持有人的所有对象中的对象,在我的测试情景,它所持有在HashSet的那些对象:

private readonly HashSet<TEntity> _entitiesCollection = new HashSet<TEntity>(); 

哪里TEntity是offcourse的Person实体。

此外,这个类有一个List<PropertyInfo>' object, named _keyProperties`,它将包含对象的所有关键字。

现在,我确实有这种会发现所有的作为给定对象的一个​​关键属性的方法:

private void GetKeyProperties() 
{ 
    _keyProperties = new List<PropertyInfo>(); 
    var properties = typeof(TEntity).GetProperties(); 

    foreach (var property in from property in properties from attribute in property.GetCustomAttributes(true).OfType<KeyAttribute>() select property) 
    { _keyProperties.Add(property); } 
} 

没有,比如,你可以选择你所有的,对于匹配的给定值主键。这可以用类似的方法来实现:

protected virtual TEntity Find(params object[] keyValues) 
{ 
    if (keyValues.Length != _keyProperties.Count) throw new ArgumentException("Incorrect number of keys passed to find method"); 

    var keyQuery = this.AsQueryable(); 
    keyQuery = keyValues.Select((t, i) => i).Aggregate(keyQuery, (current, x) => current.Where(entity => _keyProperties[x].GetValue(entity, null).Equals(keyValues[x]))); 

    return keyQuery.SingleOrDefault(); 
} 

或者,例如,如果要执行一个实体的更新,你可以执行以下命令:

public void Update(TEntity entity) 
{ 
    // First the original entity is retrieve by searching the key, this item is then removed from the collection 
    // Then a new item is being added to the collection. 
    var original = Find(_keyProperties.Select(e => e.GetValue(entity)).ToArray()); 
    Detach(original); 

    _entitiesCollection.Add(entity); 
} 

这样做是搜索原始实体基于主键,删除该实体,然后再次添加更新的实体。

所以,我希望这有助于。