1

我有一个多对多映射/数据透视表,我必须将其公开为一个实体,以便对类似于以下的关系进行建模(根据这个问题Model Entity Framework many-many plus shared relationship):

在此处输入图像描述

现在,我想模拟“库存”实体框架多对多关系的导航属性上存在的 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.Anthologies)的 Composition.Composer == Anthology.Composer . 这是联结表所持有的关系:

在此处输入图像描述

即不得有与选集相关的作品,但有不同的作曲家。

4

1 回答 1

0

这是我目前的解决方案。仍然对建议持开放态度,因为这会掩盖 IQueryable,它会对性能产生影响。它也没有上下文,所以不能删除连接(注意 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;
        }
    }
}
于 2013-05-02T19:30:44.430 回答