我有一个多对多的映射/数据透视表我不得不作为实体公开,以便建模类似于以下的关系(根据此问题Model Entity Framework many-many plus shared relation):
现在,我想模拟“库存”实体框架多对多关系的导航属性中存在的EF集合枚举/添加/删除功能。我该怎么做?
我希望能在不破坏数据性能的情况下继续查询。显然,只是实现以下来桥接数据透视表并不能实现这一目标,也不遵循EF约定来管理集合:
public partial class Composition {
public IEnumerable<Anthology> Anthologies {
get {
return CompositionAnthologies.Select(e => e.Anthology);
}
}
public void AddAnthology(Anthology anthology)
{
CompositionAnthologies.Add(new CompositionAnthology() {
Anthology = anthology,
Composer = Composer
});
}
}
你能指出一个例子或推荐一个起点吗? (注意我目前正在使用模型优先,但是会转向代码优先解决方案,因为模型优先似乎很快成为二等公民。)
编辑:这是关于关系和约束的进一步信息。
多对多关系有一个联结表(“CompositionAnthologies”),包括一个绑定的ComposerId列,必要的手动创建的FK关系,以强制所有Anthology.Compositions(和Composition)的Composition.Composer == Anthology.Composer .Anthologies)。以下是联结表所保持的关系:
即必须没有与选集有关的作品,但有不同的作曲家。
答案 0 :(得分:0)
这是我目前的解决方案。仍然愿意接受建议,因为这会掩盖IQueryable,它具有性能影响。它也没有Context,因此无法删除联结(请注意NotImplemented异常)。后一个问题对我来说并不是非常重要,因为我的数据有一个删除的标志,无论如何我都会使用。
这是关系的一面。它们是对称的。
public partial class Composition {
public ICollection<Anthology> Anthologies {
get {
return new JunctionedAnthologies(this);
}
}
}
public class JunctionedAnthologies : ICollection<Anthology> {
private readonly Composition _parent;
public JunctionedAnthologies(Composition parent)
{
_parent = parent;
}
public void Add(Anthology item) {
if (item.Composer == null) {
if (_parent.Composer == null) throw new InvalidOperationException("The parent or child Composer must be set to form this association");
item.Composer = _parent.Composer;
}
else if (_parent.Composer == null) {
_parent.Composer = item.Composer;
}
else if (item.Composer != _parent.Composer) {
throw new InvalidOperationException("The parent and child must not have a differing Composer assigned");
}
junction.Add(new CompositionAnthology() {
Anthology = item,
Composer = item.Composer
});
}
public void Clear() {
throw new NotImplementedException();
}
public bool Contains(Anthology item) {
return junction.Any(j => j.Anthology == item);
}
public void CopyTo(Anthology[] array, int arrayIndex) {
throw new NotImplementedException();
}
public int Count {
get { return junction.Count; }
}
public bool IsReadOnly {
get { return false; }
}
public bool Remove(Anthology item) {
throw new NotImplementedException();
}
public IEnumerator<Anthology> GetEnumerator() {
return junction.Select(e => e.Anthology).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
private ICollection<CompositionAnthology> junction {
get {
return _parent.CompositionAnthologies;
}
}
}