【问题标题】:Mapping generic Many-Many with custom key names使用自定义键名映射通用多对多
【发布时间】:2018-08-13 13:43:19
【问题描述】:
public class Entity1
{
    public int Id { get; set; }
    public Guid EntityKey { get; set; }
    public ICollection<Entity2> Entity2s { get; set; }
}

public class Entity2
{
    public int Id { get; set; }
    public Guid EntityKey { get; set; }
}

public class EntityMapping 
{
    public int Id { get; set; }
    public Guid ParentKey { get; set; }
    public EntityType ParentType { get; set; }
    public Guid ChildKey { get; set; }
    public EntityType ChildType { get; set; }
}

我需要使用 fluent 配置 API 做一些事情来执行:

select e2.* from Entity1 e1
join Entitymapping em on em.ParentKey == e1.EntityKey && em.ParentType == 'Entity1'
join Entity2 e2 on em.ChildKey == e2.EntityKey

当我打电话时:entity1.Entity2s.ToList()

仅使用 EF 4 中的 fluent 配置是否也能做到这一点?

【问题讨论】:

    标签: c# entity-framework entity-framework-4


    【解决方案1】:

    好的,首先。为什么不使用 Id 字段作为主要字段?由 SQL Server 维护为唯一的,等等。每个实体有两个键正在自找麻烦。

    与我给here的MM答案几乎相同

    您的实体需要一些工作。 Entity1/Entity2 导航属性应指向 List 并且 EntityMapping 应指向 Entity1 和 Entity2 中的每一个。这是一个 1-1 的连接表,其中每一边都可以有很多,因此是多对多。如果您希望所有 Entity1 及其关联的 Entity2 更像这样:

    DbSet.Entity1.Include("EntityMapping").Include("EntityMapping.Entity2").ToList();

    使用单个表来存储许多不同实体之间的关系仍然可以使用类似的结构。将有一些“幕后”检查来强制 1-1 或 1-M 关系进入 M-M 模式,打赌这应该让你开始......

    public class Entity1
    {
        public int Id { get; set; }
        public Guid EntityKey { get; set; }
        public EntityType E1Type { get; set; }
        public ICollection<EntityMapping> Entity2s { get; set; }
    }
    
    public class Entity2
    {
        public int Id { get; set; }
        public Guid EntityKey { get; set; }
        public EntityType E2Type { get; set; }
        public ICollection<EntityMapping> Entity1s { get; set; }
    }
    
    public class EntityMapping 
    {
        public int Id { get; set; }
        public int ParentKey { get; set; }
        public int ChildKey { get; set; }
        public Entity1 Entity1 { get; set; }
        public Entity2 Entity2 { get; set; }
    }
    

    对于所有名为“Foo”的实体和“Bar”子实体(假设 Foo 也可能与“Widgets”相关,有一种 EF“方式”可以做到这一点,但您要使用的 SQL SELECT 是

    select e1.EntityKey as e1Key, e2.EntityKey as e2Key from Entity1 e1
    inner join EntityMapping e3 on e3.ParentKey = e1.Id
    inner join Entity2 e2 on e2.Id = e3.ChildKey
    where e1.E1Type = "Foo" and e2.E2Type = "Bar"
    

    EF 说话

    var temp = DbSet.Entity1.Select(p => p.E1Type == "Foo").Include("EntityMapping").Include("EntityMapping.Entity2");
    var result = temp.Where(r => r.E2Type == "Bar").ToList();
    

    可能可以将这些结合起来,但我必须修补而不是“即兴发挥”。那更好吗?

    【讨论】:

    • EF 加载参考更像 DbSet.Entity2.ToList()。
    • 它没有使用主要的,因为这个映射表正在被许多不同类型的实体重用
    • 好的,所以 Guid 只是数据,而不是键。因此不要在关系中使用。例子是准确的。
    • 思考:或者您是说有许多不同的 Entity1/Entity2 表共享此连接方法?
    • 这是一个庞大的遗留应用程序,我们不得不将我们的地址抽象为“空间”。我们可以通过我们的存储库访问所有内容,但是直接在 Domain 类中引用类型并让配置处理连接会更好。底线是我们的架构看起来是这样的,我只需要知道这是否可以通过 fluent API 实现。我不在乎它是否“正确”...
    猜你喜欢
    • 1970-01-01
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多