繁体   English   中英

有没有办法在Entity Framework中建模可选的多对多关系?

[英]Is there a way to model an optional many-to-many relationship in Entity Framework?

实体框架中是否有一种方法(我假设它将使用流畅的语法,因为数据注释有些限制)来建模多对多关系,其中双方都是可选的(0..M到0..N)关系)? 用例是这样的:我想允许用户向实体添加标签。 标签到实体是M:N关系,但两者都不是必需的。 也就是说,可以存在不应用于任何实体的标签,并且实体可以是未标记的。 这对我来说似乎相当合理。 我不能简单地使用以下模型:

public virtual ICollection<Tag> Tags { get; set; }

public virtual ICollection<Entity> Entities { get; set; }

因为每个类都有其他关系,并且我得到“外键约束可能导致循环或多个级联路径”。 我希望也许我可以这样做:

modelBuilder.Entity<Tag>().HasOptional(t => t.Entities);
modelBuilder.Entity<Entity>().HasOptional(t => t.Tags);

但我被警告称,EF“无法确定该协会的主要目标。” 从阅读来看,似乎这种关系必须有一个主要目的,但就我而言,这是不可取的。

我可以添加一个类来表示桥表并手动处理映射,但我宁愿不要混淆代码。 我想知道是否还有另一种方法可以在EF中对此进行建模。

要填写更多细节,还有一个Author类(相当于Users)。 作者和标签是1:M,作者与实体也是1:M。 当然,问题是实体类在级联树中出现两次。 使标记/实体关系可选将解决此问题。 我还可以修复它,如果有办法通过实体获得标签,但由于标签可以存在而不连接到实体,我认为这是不可能的。

以下是相关代码的摘要:

public class Author
{
    public Guid Id { get; set; }
    public virtual List<Entity> Entities { get; set; }
    public virtual List<Tag> Tags { get; set; }
}

public class Tag
{
    public Guid Id { get; set; }
    public Guid AuthorId { get; set; }
    public virtual Author Author { get; set; }
    public virtual ICollection<Entity> Entities { get; set; }
}

public class Entity
{
    public Guid Id { get; set; }
    public Guid AuthorId { get; set; }
    public virtual Author Author { get; set; }
    public virtual ICollection<Tag> Tags { get; set; }
}

编辑:

使用.HasMany().WithMany()下面建议的.HasMany().WithMany()给我这个:

CREATE TABLE [dbo].[TagEntities] (
    [Tag_Id] [uniqueidentifier] NOT NULL,
    [Entity_Id] [uniqueidentifier] NOT NULL,
    CONSTRAINT [PK_dbo.TagEntities] PRIMARY KEY ([Tag_Id], [Entity_Id])
)

但我想要的是Tag_Id和Entity_Id在这个表上可以为空。 也许这个模型没有像我想的那么有意义? 你能有一个双面都可以为空的桥牌桌吗?

使用

modelBuilder.Entity<Tag>().HasMany(t => t.Entities)
    .WithMany(t => t.Tags);

代替

modelBuilder.Entity<Tag>().HasOptional(t => t.Entities);
modelBuilder.Entity<Entity>().HasOptional(t => t.Tags);

我不知道这是否是正确的答案,但我通过创建一个名为DbEntity的基类来解决这个问题,其他类继承自该类。 所以现在作者刚才:

// Both entities and tags are part of this collection
public virtual List<DbEntity> Entities { get; set; }

“实体”(在我的代码中具有特殊含义)和“标签”都是DbEntity的子类。 这消除了多个级联路径,同时保留了导航属性,但我确实需要这样做:

author.Entities.OfType<Tag>();

要么

author.Entities.OfType<Entity>();

获取特定的实体集。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM