Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.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,我试图使用代码优先实体框架在名为Sector和Ship的两个类之间建立一个简单的双向关系。这里的想法是扇区可以有零到多个船舶,其中船舶始终有一个扇区,它是当前位置 出于导航目的,我希望在关系的两边都有一个属性。因此,classSector包含类型为ICollection的属性,其中Ship包含类型为Sector的属性 Sector的主键是X和Y的组合 public class Ship { public int ID { get; set; } public string Nam

我试图使用代码优先实体框架在名为SectorShip的两个类之间建立一个简单的双向关系。这里的想法是
扇区
可以有零到多个
船舶
,其中
船舶
始终有一个
扇区
,它是当前位置

出于导航目的,我希望在关系的两边都有一个属性。因此,class
Sector
包含类型为
ICollection
的属性,其中
Ship
包含类型为
Sector
的属性

Sector
的主键是
X
Y
的组合

public class Ship
{
    public int ID { get; set; }
    public string Name { get; set; }
    public double Speed { get; set; }

    public virtual Sector Sector { get; set; }
    //public virtual Sector Destination { get; set; }
}

public class Sector
{
    public Int64 X { get; set; }
    public Int64 Y { get; set; }

    public virtual ICollection<Ship> Ships { get; set; }
}

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        // combined key for sector
        modelBuilder.Entity<Sector>()
            .HasKey(s => new { s.X, s.Y });
    }
问题是,只要我在
船舶
扇区
之间建立另一个关系,即它的
目的地
,前面提到的关系就会在两侧用外键创建。首先,我想知道为什么,其次,如何防止它发生?我不认为有必要,这导致第一个关系不能从两侧导航,因为
扇区X
扇区Y
都是
NULL
扇区X1
扇区Y1
都是
NULL
。它们代表相同的东西

Sector
 - X
 - Y
Ship
 - ID
 - Name
 - Speed
 - Sector_X
 - Sector_Y
 - Destination_X
 - Destination_Y
 - Sector_X1
 - Sector_X2

添加
目的地
属性时,您还需要在
扇区
类中包括导航集合,例如
收入船舶
。或者不要在
扇区
类上添加任何导航集合

我假设当有两个导航属性从
Ship
Sector
时,EF会感到困惑,但是
Sector
中只有一个
Ship
集合,所以它会继续创建3个FK对

使用:

--或--

如果你在“关系约定”下查看,它会说

如果相同类型之间存在多个关系(例如,假设您定义了Person和Book类,其中Person类包含ReviewBooks和AuthoredBooks导航属性,Book类包含Author和Reviewer导航属性)您需要使用数据注释或fluent API手动配置关系

由于
船舶
扇区
之间存在多个关系,EF无法确定
船舶
上的哪个导航属性与
扇区
上的集合属性相反,并为
扇区.Ships
创建单独的关系

您需要使用(这里有一个示例,但还有其他方法):

公营部门
{
公共Int64 X{get;set;}
公共Int64 Y{get;set;}
[反向财产(“部门”)]
公共虚拟ICollection{get;set;}
}
或:

模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
//其他东西。。。
modelBuilder.Entity()
.HasRequired(p=>p.Sector)
.有许多(p=>p.Ships);
modelBuilder.Entity()
.HasRequired(p=>p.Destination)
.有很多
.WillCascadeOnDelete();
}

由于
扇区
配送
有多个1:many关系,您可能必须使用Fluent API,因为您需要将至少一个关系设置为默认情况下不级联删除(或将
配送目的地
设置为可选),或者您将获得“多个级联路径”错误。

我认为EF可能会感到困惑,因为它不知道
Sector.Ships
是否是
Ship.Sector
Ship.Destination
的反义词,因为这对我来说似乎很有用。然而,正是jjj的回答让我理解了围绕我的问题的“为什么”。在你们两人之间,你们设法帮助了我,我相信他的答案应该是被接受的,仅仅是因为参考的理论背景。不过我还是非常感谢你的加入+1.
Sector
 - X
 - Y
Ship
 - ID
 - Name
 - Speed
 - Sector_X
 - Sector_Y
 - Destination_X
 - Destination_Y
 - Sector_X1
 - Sector_X2
public class Ship {
    public int ID { get; set; }
    public string Name { get; set; }
    public double Speed { get; set; }

    public virtual Sector Sector { get; set; }
    public virtual Sector Destination { get; set; }
}

public class Sector {
    public Int64 X { get; set; }
    public Int64 Y { get; set; }
}
public class Ship {
    public int ID { get; set; }
    public string Name { get; set; }
    public double Speed { get; set; }

    public virtual Sector Sector { get; set; }
    public virtual Sector Destination { get; set; }
}

public class Sector {
    public Int64 X { get; set; }
    public Int64 Y { get; set; }

    public virtual ICollection<Ship> Ships { get; set; }
    public virtual ICollection<Ship> IncomingShips { get; set; }
}

protected override void OnModelCreating(DbModelBuilder modelBuilder) {
    .....
    modelBuilder.Entity<Sector>()
                .HasMany(p => p.Ships)
                .WithRequired(p => p.Sector)
                .WillCascadeOnDelete(false);

    modelBuilder.Entity<Sector>()
                .HasMany(p => p.IncomingShips)
                .WithRequired(p => p.Destination)
                .WillCascadeOnDelete(false);
}
Sector
 - X
 - Y
Ship
 - ID
 - Name
 - Speed
 - Sector_X
 - Sector_Y
 - Destination_X
 - Destination_Y
public class Sector
{
    public Int64 X { get; set; }
    public Int64 Y { get; set; }

    [InverseProperty("Sector")] 
    public virtual ICollection<Ship> Ships { get; set; }
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // other stuff...
    modelBuilder.Entity<Ship>()
        .HasRequired(p => p.Sector)
        .WithMany(p => p.Ships);

    modelBuilder.Entity<Ship>()
        .HasRequired(p => p.Destination)
        .WithMany()
        .WillCascadeOnDelete();
}