Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/magento/5.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#_Database_Entity Framework Core - Fatal编程技术网

C# 实体框架核心-两个实体之间的多个一对多关系

C# 实体框架核心-两个实体之间的多个一对多关系,c#,database,entity-framework-core,C#,Database,Entity Framework Core,我有两个实体-团队和游戏。一个队可以有很多比赛(一对多) 所以看起来是这样的: public class Team { public int Id { get; set; } public string Name { get; set; } public ICollection<Game> Games { get; set; } } public class Game { public i

我有两个实体-团队游戏。一个队可以有很多比赛(一对多)

所以看起来是这样的:

 public class Team
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public ICollection<Game> Games { get; set; }
    }

 public class Game
    {
        public int Id { get; set; }
        public DateTime Date { get; set; }

        public int TeamId { get; set; }
        public Team Team { get; set; }
    }
公共类团队
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共ICollection游戏{get;set;}
}
公开课游戏
{
公共int Id{get;set;}
公共日期时间日期{get;set;}
public int TeamId{get;set;}
公共团队{get;set;}
}
这很好,但我想通过将游戏分为两大类——主场和客场游戏,使其更加精致。然而,这将在这两个实体之间引入另一种关系,我不确定如何定义它

我想会是这样的

 public class Team
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public ICollection<Game> HomeGames { get; set; }
        public ICollection<Game> AwayGames { get; set; }
    }

public class Game
    {
        public int Id { get; set; }
        public DateTime Date { get; set; }

        public int HomeTeamId { get; set; }
        public Team HomeTeam { get; set; }

        public int AwayTeamId{ get; set; }
        public Team AwayTeam { get; set; }
    }
公共类团队
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共ICollection家庭游戏{get;set;}
公共ICollection AwayGames{get;set;}
}
公开课游戏
{
公共int Id{get;set;}
公共日期时间日期{get;set;}
public int HomeTeamId{get;set;}
公共团队主队{get;set;}
公共int{get;set;}
公共团队AwayTeam{get;set;}
}
这样做会混淆实体框架,它无法决定如何解决关系


有什么想法吗?

您必须告诉实体框架在一个关联中涉及两个实体中的哪些属性。在fluent mapping API中,这是:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Team>().HasMany(t => t.HomeGames)
        .WithOne(g => g.HomeTeam)
        .HasForeignKey(g => g.HomeTeamId);
    modelBuilder.Entity<Team>().HasMany(t => t.AwayGames)
        .WithOne(g => g.AwayTeam)
        .HasForeignKey(g => g.AwayTeamId).OnDelete(DeleteBehavior.Restrict);
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity().HasMany(t=>t.HomeGames)
.WithOne(g=>g.HomeTeam)
.HasForeignKey(g=>g.HomeTeamId);
modelBuilder.Entity().HasMany(t=>t.AwayGames)
.带一个(g=>g.AwayTeam)
.HasForeignKey(g=>g.AwayTeamId).OnDelete(DeleteBehavior.Restrict);
}
您必须使用fluent API,因为默认情况下,EF将尝试使用级联删除创建两个外键。SQL Server不允许这样做,因为它臭名昭著的“多级联路径”限制。其中一个键不应该是级联的,这只能由fluent API配置。

基于您可以使用数据注释

数据注释

有两种数据注释可用于配置 关系、[ForeignKey]和[InverseProperty]

[外键]

您可以使用数据注释来配置 属性应用作给定对象的外键属性 关系这通常在启用外键属性时完成 没有被惯例发现的

[逆属性]

您可以使用数据注释来配置 从属实体和主体实体对上的导航属性。 这通常在存在多对导航时完成 两个实体类型之间的属性

公共类团队
{
公共int Id{get;set;}
公共字符串名称{get;set;}
[逆属性(“主队”)]
公共ICollection家庭游戏{get;set;}
[反向属性(“AwayTeam”)]
公共ICollection AwayGames{get;set;}
}
公开课游戏
{
公共int Id{get;set;}
公共日期时间日期{get;set;}
public int HomeTeamId{get;set;}
[ForeignKey(“HomeTeamId”)]
公共团队主队{get;set;}
公共int{get;set;}
[外键(“AwayTeamId”)]
公共虚拟团队AwayTeam{get;set;}
}
如果使用db.Database.Migrate(),则会出现错误

System.Data.SqlClient.SqlException:'引入外键 表“Games”上的约束“FK\U Games\U Team\U HomeTeamId”可能导致 循环或多个级联路径。指定ON DELETE NO ACTION或ON 不更新任何操作,或修改其他外键约束。不能 创建约束或索引。请参阅以前的错误

您可以将HomeTeamId设置为可为空

public class Team
    {
        public int Id { get; set; }
        public string Name { get; set; }

        [InverseProperty("HomeTeam")]
        public ICollection<Game> HomeGames { get; set; }

        [InverseProperty("AwayTeam")]
        public ICollection<Game> AwayGames { get; set; }
    }

public class Game
    {
        public int Id { get; set; }
        public DateTime Date { get; set; }

        public int? HomeTeamId { get; set; }
        [ForeignKey("HomeTeamId")]
        public Team HomeTeam { get; set; }

        public int? AwayTeamId{ get; set; }
        [ForeignKey("AwayTeamId")]
        public virtual Team AwayTeam { get; set; }
    }
公共类团队
{
公共int Id{get;set;}
公共字符串名称{get;set;}
[逆属性(“主队”)]
公共ICollection家庭游戏{get;set;}
[反向属性(“AwayTeam”)]
公共ICollection AwayGames{get;set;}
}
公开课游戏
{
公共int Id{get;set;}
公共日期时间日期{get;set;}
public int?HomeTeamId{get;set;}
[ForeignKey(“HomeTeamId”)]
公共团队主队{get;set;}
公共int?AwayTeamId{get;set;}
[外键(“AwayTeamId”)]
公共虚拟团队AwayTeam{get;set;}
}
或者看

  • 这里是我测试并运行的完整代码(db first而不是code first

  • 对于代码,请先使用int?

  • 对于Program.cs

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations.Schema;
    using Microsoft.EntityFrameworkCore;
    
    namespace stackoverflow54196199
    {
    
    public class Team
    {
    
        public int Id { get; set; }
        public string Name { get; set; }
    
        [InverseProperty("HomeTeam")]
        public ICollection<Game> HomeGames { get; set; }
    
        [InverseProperty("AwayTeam")]
        public ICollection<Game> AwayGames { get; set; }
    }
    
    public class Game
    {
        public int Id { get; set; }
        public DateTime Date { get; set; }
    
        public int HomeTeamId { get; set; }
        [ForeignKey("HomeTeamId")]
        public Team HomeTeam { get; set; }
    
        public int AwayTeamId { get; set; }
        [ForeignKey("AwayTeamId")]
        public Team AwayTeam { get; set; }
    }
    
    
    public class MyContext : DbContext
    {
        public DbSet<Game> Games { get; set; }
        public DbSet<Team> Teams { get; set; }
    
    
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer("Server=.;Integrated Security=true;Initial Catalog=stackoverflow54196199;Persist Security Info=False;");
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            var db = new MyContext();
            foreach (var game in db.Games.Include(i => i.AwayTeam).Include(i => i.HomeTeam))
            {
                Console.WriteLine(game.HomeTeam.Name);
                Console.WriteLine(game.AwayTeam.Name);
    
            }
            Console.ReadLine();
        }
    }
    }
    
    使用系统;
    使用System.Collections.Generic;
    使用System.ComponentModel.DataAnnotations.Schema;
    使用Microsoft.EntityFrameworkCore;
    命名空间堆栈溢出54196199
    {
    公开课小组
    {
    公共int Id{get;set;}
    公共字符串名称{get;set;}
    [逆属性(“主队”)]
    公共ICollection家庭游戏{get;set;}
    [反向属性(“AwayTeam”)]
    公共ICollection AwayGames{get;set;}
    }
    公开课游戏
    {
    公共int Id{get;set;}
    公共日期时间日期{get;set;}
    public int HomeTeamId{get;set;}
    [ForeignKey(“HomeTeamId”)]
    公共团队主队{get;set;}
    公共int{get;set;}
    [外键(“AwayTeamId”)]
    公共团队AwayTeam{get;set;}
    }
    公共类MyContext:DbContext
    {
    公共DbSet游戏{get;set;}
    公共DbSet团队{get;set;}
    配置时受保护的覆盖无效(DBContextOptions Builder Options Builder)
    {
    o
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations.Schema;
    using Microsoft.EntityFrameworkCore;
    
    namespace stackoverflow54196199
    {
    
    public class Team
    {
    
        public int Id { get; set; }
        public string Name { get; set; }
    
        [InverseProperty("HomeTeam")]
        public ICollection<Game> HomeGames { get; set; }
    
        [InverseProperty("AwayTeam")]
        public ICollection<Game> AwayGames { get; set; }
    }
    
    public class Game
    {
        public int Id { get; set; }
        public DateTime Date { get; set; }
    
        public int HomeTeamId { get; set; }
        [ForeignKey("HomeTeamId")]
        public Team HomeTeam { get; set; }
    
        public int AwayTeamId { get; set; }
        [ForeignKey("AwayTeamId")]
        public Team AwayTeam { get; set; }
    }
    
    
    public class MyContext : DbContext
    {
        public DbSet<Game> Games { get; set; }
        public DbSet<Team> Teams { get; set; }
    
    
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer("Server=.;Integrated Security=true;Initial Catalog=stackoverflow54196199;Persist Security Info=False;");
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            var db = new MyContext();
            foreach (var game in db.Games.Include(i => i.AwayTeam).Include(i => i.HomeTeam))
            {
                Console.WriteLine(game.HomeTeam.Name);
                Console.WriteLine(game.AwayTeam.Name);
    
            }
            Console.ReadLine();
        }
    }
    }
    
    <PropertyGroup>
      <OutputType>Exe</OutputType>
      <TargetFramework>netcoreapp2.1</TargetFramework>
    </PropertyGroup>
    
    <ItemGroup>
      <PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.0" />
      <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="2.1.0" />
      <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.1.0" />
     </ItemGroup>