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
Entity framework 实体框架4.1 Fluent API中的一对多连接表和可选关系_Entity Framework_Entity Framework 4.1_Ef Code First - Fatal编程技术网

Entity framework 实体框架4.1 Fluent API中的一对多连接表和可选关系

Entity framework 实体框架4.1 Fluent API中的一对多连接表和可选关系,entity-framework,entity-framework-4.1,ef-code-first,Entity Framework,Entity Framework 4.1,Ef Code First,同样,使用无法更改的遗留数据库,并使用EntityFramework4.1和FluentAPI仅读取数据 public class Client { [Key] public int ClientID { get; set; } public string Name { get; set ;} public virtual ICollection<Phone> Phones { get; set; } } public class Phone { [Key]

同样,使用无法更改的遗留数据库,并使用EntityFramework4.1和FluentAPI仅读取数据

public class Client
{
  [Key]
  public int ClientID { get; set; }
  public string Name { get; set ;}

  public virtual ICollection<Phone> Phones { get; set; }
}

public class Phone
{
  [Key]
  public int PhoneID { get; set; }
  public string Number { get; set; }

  public virtual Client Client { get; set; }
}

public class ClientPhone
{
  [Key]
  [Column(Order=0)]
  public int ClientID { get; set; }

  [Key]
  [Column(Order=1)]
  public int PhoneID { get; set; }
}
公共类客户端
{
[关键]
public int ClientID{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection电话{get;set;}
}
公用电话
{
[关键]
公共int PhoneID{get;set;}
公共字符串编号{get;set;}
公共虚拟客户端{get;set;}
}
公共类客户端电话
{
[关键]
[第列(顺序=0)]
public int ClientID{get;set;}
[关键]
[第列(顺序=1)]
公共int PhoneID{get;set;}
}
我希望客户端有许多电话,但电话应该只有一个可选的客户端。 注意:手机应该只有0 | 1个客户端。我不想要多对多。 因此,我尝试了以下方法:

modelBuilder.Entity<Client>()
  .HasMany(c => c.Phones)
  .WithOptional(p => p.Client)
  .Map(m =>
    {
      m.MapKey("ClientID");
      m.ToTable("ClientPhone");
    });

modelBuilder.Entity<Phone>()
  .HasOptional(p => p.Client)
  .WithMany(c => c.Phones)
  .Map(m =>
    {
      m.MapKey("PhoneID");
      m.ToTable("ClientPhone");
    });
modelBuilder.Entity()
.HasMany(c=>c.Phones)
.WithOptional(p=>p.Client)
.Map(m=>
{
m、 MapKey(“客户ID”);
m、 ToTable(“客户电话”);
});
modelBuilder.Entity()
.has可选(p=>p.Client)
.有许多(c=>c.电话)
.Map(m=>
{
m、 MapKey(“PhoneID”);
m、 ToTable(“客户电话”);
});
我尝试了几种排列,通常会得到一个关于“类型中的每个属性名称必须是唯一的”的错误

谢谢你的帮助

用答案编辑

下面是我对实体类所做的修改。可以从一个客户端导航到多个电话,也可以从一个电话导航到一个客户端,但必须浏览ClientPhone连接表

[Table("Client")]
public class Client
{
  [Key]
  [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  public int ClientID { get; set; }

  public string Name { get; set ;}

  public virtual ICollection<Phone> Phones { get; set; } // Client has * Phones
}

[Table("Phone")]
public class Phone
{
  [Key]
  [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  public int PhoneID { get; set; }

  public string Number { get; set; }

  public virtual Client Client { get; set; } // Phone has 0|1 Client
}

[Table("ClientPhone")]
public class ClientPhone
{
  // Removed the Key attribute
  public int ClientID { get; set; }

  [Key] // Left the Key on the 0|1 side
  [ForeignKey("Phone")]
  public int PhoneID { get; set; }

  public virtual Client Client { get; set; } // One Client
  public virtual Phone Phone { get; set; } // One Phone
}
[表(“客户端”)]
公共类客户端
{
[关键]
[数据库生成(DatabaseGeneratedOption.Identity)]
public int ClientID{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection电话{get;set;}//客户端有*个电话
}
[表格(“电话”)]
公用电话
{
[关键]
[数据库生成(DatabaseGeneratedOption.Identity)]
公共int PhoneID{get;set;}
公共字符串编号{get;set;}
公共虚拟客户端{get;set;}//电话有0 | 1个客户端
}
[表(“客户电话”)]
公共类客户端电话
{
//删除了键属性
public int ClientID{get;set;}
[键]//将键留在0 | 1侧
[外键(“电话”)]
公共int PhoneID{get;set;}
公共虚拟客户端{get;set;}//一个客户端
公共虚拟电话{get;set;}//一部电话
}

您不需要在此处两次指定手机和客户端之间的关系。只使用一个这样的

modelBuilder.Entity<Client>().HasMany(c => c.Phones).WithMany(i => i.Clients)
                .Map(t => t.MapLeftKey("PhoneID")
                    .MapRightKey("ClientID")
                    .ToTable("ClientPhone"));
modelBuilder.Entity()
.Map(t=>t.MapLeftKey(“PhoneID”)
.MapRightKey(“客户端ID”)
.ToTable(“客户电话”);
你不需要有模型来映射关系表,比如“ClientPhone”,因为EF会处理它。如果你有一个遗留数据库,你可以像我的回答中那样自定义映射。正如@Ladislav Mrnka所说,对于数据库级别的一对多关系,您不希望为关系保留单独的表。为此,

public class Client
{
  [Key]
  public int ClientID { get; set; }
  public string Name { get; set ;}

  public virtual ICollection<Phone> Phones { get; set; }
}

public class Phone
{
  [Key]
  public int PhoneID { get; set; }
  public string Number { get; set; }

  public virtual Client Client { get; set; }
}
公共类客户端
{
[关键]
public int ClientID{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection电话{get;set;}
}
公用电话
{
[关键]
公共int PhoneID{get;set;}
公共字符串编号{get;set;}
公共虚拟客户端{get;set;}
}
有了EF,这就足够了。它将在Phone表中创建两个带有clientId列的表,以保持关系

问题是在旧数据库中有单独的关系表。我认为旧数据库是为多对多关系定义的。请重新考虑域逻辑


如果您想保持一对多关系,我认为您可以在域级别定义多对多关系(电话有多个客户端,客户端在模型类别中有多个电话),并且在您的业务层中添加验证以仅为电话保留一个客户端

一对多关系不必加入(连接)表。如果数据库使用连接表将客户端连接到电话,则必须使用多对多关系(电话可以有多个客户端)正如@Jayantha所描述的。

我更新了问题,使之更为明确……我需要手机只有0 | 1个客户端。感谢Jayantha的透彻回答。在这和@Ladislav Mrnka的回答之间,答案是完整的。我相信我发布的解决方案适合我的情况,但你的答案仍然是可能的。你的表是如何定义的?哪些表你在数据库中有什么关系以及配置了什么关系?如果数据库包含多对多和连接表,你就不能将其映射为一对多。我想我已经按照我的场景实现了它,问题还不是很清楚。你可以使用连接表在一侧创建一个1对多,在另一侧创建一个1对1,这就是我想要做的。在这种情况下,连接表是完全冗余的。我添加了我的解决方案,并很高兴了解如何消除冗余,并改进我的尝试。