2014-10-08 90 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); 
} 

這樣做是搜索原始實體基於主鍵,刪除該實體,然後再次添加更新的實體。

所以,我希望這有助於。