.NET核心实体框架多对多关系相同的实体(相关产品)

时间:2017-09-08 13:40:14

标签: c# .net asp.net-mvc entity-framework asp.net-core

我试图在.NET Core 1.1 MVC应用程序中使用Entity Framework构建相关项类型模型。我一直遇到以下错误(尝试了deletebehaviours与外键的所有组合):

  

引入FOREIGN KEY约束   ' FK_MenuItemRelation_MenuItems_RelatedMenuItemId'桌子上   ' MenuItemRelation'可能会导致循环或多个级联路径。指定   ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN   关键约束。无法创建约束或索引。见前   错误。

在我去之前简单地使用映射表之前,我想听听社群对此的意见。

模型构建器

        //MenuItem <> MenuItem many to many (related item) mapping
        modelBuilder.Entity<MenuItemRelation>()
             .HasKey(mr => new { mr.PrimaryMenuItemId, mr.RelatedMenuItemId });

        modelBuilder.Entity<MenuItemRelation>()
             .HasOne(mr => mr.PrimaryMenuItem)
             .WithMany()
             .HasForeignKey(mr => mr.PrimaryMenuItemId);

         modelBuilder.Entity<MenuItemRelation>()
             .HasOne(mr => mr.RelatedMenuItem)
             .WithMany()
             .HasForeignKey(mr => mr.RelatedMenuItemId).OnDelete(DeleteBehavior.Restrict);

域模型

public class MenuItem
{
    public string Category { get; set; }
    public string Description { get; set; }
    public long ID { get; set; }
    public Menu Menu { get; set; }
    public string Name { get; set; }
    public string PictureUrls { get; set; }
    public float Price { get; set; }
    public string Reference { get; set; }
    public ICollection<MenuItemRelation> RelatedItems { get; set; }
    public string Status { get; set; }
}

映射实体

public class MenuItemRelation
{
    public MenuItem PrimaryMenuItem { get; set; }
    public long PrimaryMenuItemId { get; set; }
    public MenuItem RelatedMenuItem { get; set; }
    public long RelatedMenuItemId { get; set; }
}

1 个答案:

答案 0 :(得分:0)

因此,我使用数据库第一种方法建模了所需的SQL结果并反向设计了多对多关系,如Entity Framework Core creating model from existing database所述。结果如下。 基本上它只需要我在menuitem类上添加传入关系和传出关系。

如果有更好的方法,请随意发表评论。

表TSQL

Create TABLE MenuItem(
    ID int IDENTITY(1,1),
    Name nvarchar(max)
    PRIMARY KEY (ID)
)

GO

CREATE TABLE MenuItemRelation (
    PrimaryMenuItemId int,
    RelatedMenuItemId int,
    PRIMARY KEY (PrimaryMenuItemId, RelatedMenuItemId),
    FOREIGN KEY (PrimaryMenuItemId) REFERENCES MenuItem (ID),
    FOREIGN KEY (RelatedMenuItemId) REFERENCES MenuItem (ID)
)

GO

Insert into dbo.MenuItem values ('MenuItemA')
Insert into dbo.MenuItem values ('MenuItemB')
Insert into dbo.MenuItem values ('MenuItemC')

GO

INSERT into dbo.MenuItemRelation values (1,2)
INSERT into dbo.MenuItemRelation values (1,3)

GO

DELETE from dbo.MenuItem where ID = 1

GO

//Confirmed no cascading happens

域模型(带有一些命名编辑)

public class MenuItem
{
    public string Category { get; set; }
    public string Description { get; set; }
    public long ID { get; set; }
    public Menu Menu { get; set; }
    public string Name { get; set; }
    public string PictureUrls { get; set; }
    public float Price { get; set; }
    public string Reference { get; set; }
    public ICollection<MenuItemRelation> RelatedItems { get; set; }
    public ICollection<MenuItemRelation> RelatedTo { get; set; }
    public string Status { get; set; }
}

映射对象

public class MenuItemRelation
{
    public MenuItem PrimaryMenuItem { get; set; }
    public long PrimaryMenuItemId { get; set; }
    public MenuItem RelatedMenuItem { get; set; }
    public long RelatedMenuItemId { get; set; }
}

模型构建器

modelBuilder.Entity<MenuItemRelation>()
    .HasKey(e => new { e.PrimaryMenuItemId, e.RelatedMenuItemId });

modelBuilder.Entity<MenuItemRelation>()
    .HasOne(d => d.PrimaryMenuItem)
    .WithMany(p => p.RelatedItems)
    .HasForeignKey(d => d.PrimaryMenuItemId)
    .OnDelete(DeleteBehavior.Restrict);

modelBuilder.Entity<MenuItemRelation>()
    .HasOne(d => d.RelatedMenuItem)
    .WithMany(p => p.RelatedTo)
    .HasForeignKey(d => d.RelatedMenuItemId)
    .OnDelete(DeleteBehavior.Restrict);