EntityFramework - 数据库中的多对多引用,模型中没有反向引用

Posted

技术标签:

【中文标题】EntityFramework - 数据库中的多对多引用,模型中没有反向引用【英文标题】:EntityFramework - many-to-many reference in the DB without a backreference in the model 【发布时间】:2013-03-31 02:27:29 【问题描述】:

在我的应用程序中,用户可以定义参数,然后根据一组参数创建 SlideSet。

我使用的是代码优先实体框架 5.0,并且我有以下模型:

class SlideSet 
  public ICollection<Parameter> Parameter

class Parameter 

一个参数可能被许多幻灯片使用或根本不使用。但是,在我的域中,参数不需要引用 SlideSet,它们位于单独的有界上下文中(SlideSet 和 Parameter 都是聚合根)。因此,我不想从 Parameter 引用 SlideSet。

我想要的表模型(我不关心表/列名)是

Table SlideSet
Table Param
Table SlideSetParam
   FK_SlideSet
   FK_Param

我知道我可以通过引入 ParameterGroup 实体或 Param.SlideSets 集合来对此进行建模,但它的存在仅用于 ORM 映射目的(并导致序列化问题)。有没有其他方法可以告诉 EF 从我的实体生成这个表模型?

【问题讨论】:

我想你要找的是这个:***.com/questions/8927278/… 我认为您应该将使用 ORM 的一些副作用视为理所当然。您可以通过使集合不延迟加载来防止序列化问题。 【参考方案1】:

这应该会让你成为一个 Parameter 没有导航属性:

modelBuilder.Entity<SlideSet>()
    .HasMany(x => x.Parameters)
    .WithRequired();

编辑:

根据评论 - 这应该是相似的。这似乎很适合您尝试做的事情....

modelBuilder.Entity<SlideSet>()
    .HasMany(x => x.Parameters)
    .WithMany();

...你可以使用任何一种方式:

var slideset = new SlideSet  Parameters = new []
    
        new Parameter,
        new Parameter,
        new Parameter,
        new Parameter,
    
;
var slideset2 = new SlideSet  ;
db.SlideSets.Add(slideset);
db.SaveChanges();

var slidesets = db.SlideSets.ToList();
var parameters = db.Parameters.ToList();
Console.WriteLine("");

db.SlideSets.Add(slideset2);
db.SaveChanges();

slidesets = db.SlideSets.ToList();
parameters = db.Parameters.ToList();
Console.WriteLine("");

...和 ​​SQL:

CREATE TABLE [dbo].[Parameters] (
    [ParameterID] [int] NOT NULL IDENTITY,
    CONSTRAINT [PK_dbo.Parameters] PRIMARY KEY ([ParameterID])
)
CREATE TABLE [dbo].[SlideSets] (
    [SlideSetID] [int] NOT NULL IDENTITY,
    CONSTRAINT [PK_dbo.SlideSets] PRIMARY KEY ([SlideSetID])
)
CREATE TABLE [dbo].[SlideSetParameters] (
    [SlideSet_SlideSetID] [int] NOT NULL,
    [Parameter_ParameterID] [int] NOT NULL,
    CONSTRAINT [PK_dbo.SlideSetParameters] PRIMARY KEY ([SlideSet_SlideSetID], [Parameter_ParameterID])
)
CREATE INDEX [IX_SlideSet_SlideSetID] ON [dbo].[SlideSetParameters]([SlideSet_SlideSetID])
CREATE INDEX [IX_Parameter_ParameterID] ON [dbo].[SlideSetParameters]([Parameter_ParameterID])
ALTER TABLE [dbo].[SlideSetParameters] ADD CONSTRAINT [FK_dbo.SlideSetParameters_dbo.SlideSets_SlideSet_SlideSetID] FOREIGN KEY ([SlideSet_SlideSetID]) REFERENCES [dbo].[SlideSets] ([SlideSetID]) ON DELETE CASCADE
ALTER TABLE [dbo].[SlideSetParameters] ADD CONSTRAINT [FK_dbo.SlideSetParameters_dbo.Parameters_Parameter_ParameterID] FOREIGN KEY ([Parameter_ParameterID]) REFERENCES [dbo].[Parameters] ([ParameterID]) ON DELETE CASCADE

...这使得原始表实际上与关系“不可知”(many-to-many) - 而索引表是在后台自动生成的。

您还可以进一步自定义它并使用几乎相同的布局创建自己的 SlideSetParam(例如,如果您想在其中添加其他字段) - 只是 Parameters 必须指向它。

【讨论】:

谢谢,但是-有了这个数据库结构,一个幻灯片集可以有很多参数,但一个参数最多可以被一个幻灯片集使用。在我的例子中,一个参数可以被零个或多个幻灯片集使用,一个幻灯片集可以有零个或多个参数。我只是不希望 Parameter 对象引用 Slideset。 已经很晚了 :) - 我没有明白另一点 - 虽然它非常相似 - 我修改了它。 哦,太棒了,我今天会试试这个,但这看起来是我想要的,谢谢

以上是关于EntityFramework - 数据库中的多对多引用,模型中没有反向引用的主要内容,如果未能解决你的问题,请参考以下文章

EF Core中的多对多映射如何实现?

实体框架更改生成的多对多表的名称

使用 SQL 和 Linq 的多对多关系(实体框架/实体)

实体框架6:多对多关系问题[关闭]

EntityFramework同一张表多对多关系

数据库模式中的多对多关系表是不是有正式名称?