说我有以下对象树。我的对象树并不是真正的愚蠢,但它确实有许多多对多的关系
Account
- Users {UserId, Name, etc}
- UserPermissions {User object, Permission object}
- Permissions {PermissionId, Name, etc}
说,我想从Account对象下删除User或Permission对象。在任何一种情况下,我都希望包含已删除项目的任何UserPermission对象也从UserPermission集合中删除。
是否有一种优雅的方式,而无需手动删除UserPermission对象?我知道实体框架模型中的对象可以做到这一点,但不确定如何实现相同的结果......我没有使用EF,而是将对象结构保存到RavenDb。
根据请求,这是一个更全面的数据模型
public class Account
{
public List<User> Users {get;set;}
public List<UserGroup> UserGroups {get;set;}
public List<Alert> Alerts {get;set;}
public List<Resource> Resources {get;set;}
public List<AlertSubscription> AlertSubscriptions {get;set;}
}
public class UserGroup : IAlertSubscriber
{
public string Name {get;set;}
public List<User> Users {get;set;}
}
public class User : IAlertSubscriber
{
public string Name {get;set;}
}
public class AlertSubscription
{
public Alert Alert {get;set;}
public List<Resources> AlertPublishers {get;set;}
public List<IAlertSubscribers> AlertTargets {get;set;}
public int MinimumSeverity {get;set;}
}
所以,我希望能够做的是,如果我从Account.Users集合中删除用户,还可以从各种AlertTargets,UserGroups等中删除它。如果我从Account.UserGroups中删除UserGroup,我想要从AlertTargets中取消它,如果我从Account.Resources中删除一个资源,也从AlertSubsciptions中取出它...
答案 0 :(得分:1)
我没有尝试同步两个相同数据的副本,而是使用单一副本。您可以只拥有UserPermissions列表,还可以计算另外两个集合:
public class Account
{
private List<UserPermission> _userPersmission;
public List<UserPermission> UserPermissions
{
get { return _userPersmission; }
set { _userPersmission = value; }
}
public IEnumerable<User> Users
{
get { return _userPersmission.Select(up => up.User); }
}
public IEnumerable<Permission> Permissions
{
get { return _userPersmission.Select(up => up.Permission); }
}
}
或根据其他两个集合计算UserPermissions。但我更喜欢以前的方法,因此UserPermission可以有额外的数据。
更新:如果您无法在不重复数据的情况下计算其中一些集合的所有集合,那么您将返回观察者。在您的情况下,主题是不同的集合,如用户。如果删除某些项目,主题应通知其他馆藏。 BindingList<T>
是实施此类通知的主题。不幸的是,它没有提供有关删除了哪个项目的信息,因此您需要创建自定义绑定列表:
public class ExtendedBindingList<T> : BindingList<T>
{
public T LastRemovedItem { get; private set; }
protected override void RemoveItem(int index)
{
LastRemovedItem = base[index];
base.RemoveItem(index);
}
}
您可以使用它来获取有关项目删除的通知:
public class Account
{
public ExtendedBindingList<User> Users { get; private set; }
public Account()
{
Users = new ExtendedBindingList<User>();
Users.ListChanged += Users_ListChanged;
}
private void Users_ListChanged(object sender, ListChangedEventArgs e)
{
if (e.ListChangedType != ListChangedType.ItemDeleted)
return;
foreach (var group in UserGroups)
group.Users.Remove(Users.LastRemovedItem);
}
// ...
}
另一种选择是使用方法AddUser
和RemoveUser
来修改用户列表。并将用户列表显示为IEnumerable
:
public class Account
{
private List<User> _users = new List<User>();
public IEnumerable<User> Users { get; }
public void AddUser(User use)
{
_users.Add(user);
}
public void RemoveUser(User user)
{
_users.Remove(user);
foreach (var group in UserGroups)
group.Users.Remove(user);
}
// ...
}