Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 有没有一种方法可以在实体框架中建模可选的多对多关系?_C#_Entity Framework - Fatal编程技术网

C# 有没有一种方法可以在实体框架中建模可选的多对多关系?

C# 有没有一种方法可以在实体框架中建模可选的多对多关系?,c#,entity-framework,C#,Entity Framework,在实体框架中有没有一种方法(我假设它将使用流畅的语法,因为数据注释有些有限)来建模一个多对多关系,其中双方都是可选的(0..M到0..N关系)?用例是这样的:我希望允许用户向实体添加标记。标记到实体是一种M:N关系,但两者都不是必需的。也就是说,可以存在未应用于任何实体的标记,并且可以取消标记实体。这对我来说似乎相当合理。我不能简单地使用以下方法对此进行建模: public virtual ICollection<Tag> Tags { get; set; } 但是我想要的是,在这

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

public virtual ICollection<Tag> Tags { get; set; }
但是我想要的是,在这个表上,Tag_Id和Entity_Id可以为null。也许这个模型没有我想象的那么有意义??你能有一个两边都可以为空的桥接表吗?

使用

modelBuilder.Entity<Tag>().HasMany(t => t.Entities)
    .WithMany(t => t.Tags);
modelBuilder.Entity()
.具有多个(t=>t.Tags);
而不是

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

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

// Both entities and tags are part of this collection
public virtual List<DbEntity> Entities { get; set; }
//实体和标记都是此集合的一部分
公共虚拟列表实体{get;set;}
“实体”(在我的代码中有特殊含义)和“标记”子类DbEntity。这消除了多个级联路径,同时保留了导航属性,尽管我确实需要这样做:

author.Entities.OfType<Tag>();
author.Entities.OfType();

author.Entities.OfType();

获取特定的实体集。

是的,我看到了。问题是VisualStudio中的XML文档说
WithMany(TTarget)
将关系配置为可选:许多关系的另一端没有导航属性。但是我想要那个导航属性。但导航属性的本质可能是它们表示所需的关系。我不太确定。显然,我可以使用
Include()
来获取另一面。这可能是最好的/唯一的答案,但我会再等一段时间,看看是否还有其他问题。顺便说一句,我只是尝试了一下,但仍然出现了“循环或多个级联路径”错误。我想这可能是因为我需要去掉其中一个ICollection导航属性,但当然,如果我这样做,就无法在HasMany/WithMany中指定它。刚刚发现我读取了错误的
WithMany()
重载。所以我可能希望
.HasMany(t=>t.Entities)?出现“循环或多个级联路径”错误是由于其他原因造成的。看看我对循环级联路径这个问题的回答:这是因为当你删除一个作者时,这也会删除他的标记和实体。现在,级联删除(Author->Tag和Author->Entity)都可以尝试删除TagEntity中的相同记录。Tag\u Id或Entity\u Id可以为空是没有意义的。没有实体的标记将不会在该表中显示其标记Id。没有标记的实体将不会在该表中显示其实体Id。是的,我明白你的意思。标记不必连接到实体,但如果它没有连接,它就不会在此表中。但当连接时,两端都是必需的。那么,有没有其他方法来实现我的目标?也许我需要设置
WillCascadeOnDelete()
?当然,连接时两端都是必需的。假设标记1是与实体1和2的连接。这将在该表中放入两条记录:1-1和1-2。我真的不明白这有什么问题。实体框架还将自动使用m:n映射级联删除。这不是一个问题——这是我想要发生的,但正如您在下面提到的,“级联删除(Author->Tag和Author->Entity)都可以尝试删除TagEntity中的相同记录。”因此EF不允许我这样做。必须有办法解决这个问题……这(循环级联删除)不是EF问题,而是SQL问题。这通常表明您可能需要重新考虑您的数据模型。
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);
// Both entities and tags are part of this collection
public virtual List<DbEntity> Entities { get; set; }
author.Entities.OfType<Tag>();
author.Entities.OfType<Entity>();