我正在试图弄清楚如何将属性设置为主键。我的意思是,我有一个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 :(得分:1)
可以使用getter和setter将POCO类的PrimaryKey属性公之于众吗?
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);
}
答案 1 :(得分: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
}
我在这里使用Entity Framework,因此定义主键的属性称为Key
而不是PrimaryKey
,如您的示例所示。
现在,我确实有一个充当存储库的类。该类在对象中保存Person的所有对象,在我的测试场景中,它将这些对象保存在HashSet中:
private readonly HashSet<TEntity> _entitiesCollection = new HashSet<TEntity>();
TEntity
实体所在的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);
}
这样做是基于主键搜索原始实体,删除该实体,然后再次添加更新的实体。
所以,我希望这会有所帮助。