我有类似的东西,昨天我发现了一个解决方案,所以我很乐意分享它。 您需要知道的一点是,当您有组合键时,您尝试执行的操作将无法工作,这意味着拥有一个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);
}
这样做是搜索原始实体基于主键,删除该实体,然后再次添加更新的实体。
所以,我希望这有助于。
[关键]如果你谈论的是EF数据注解,请更具体 – InferOn 2014-10-08 06:15:15
我说的是从任何地方我使用的是类标识键属性。 – RealWorldCoder 2014-10-08 06:16:24
这些类只是运营商,不需要知道有关数据库的任何信息。 – elvin 2014-10-08 06:18:42