一对一,带有连接表和Entity Framework 4.1 Fluent API中的可选关系 [英] One to Many with a join table and an optional relationship in Entity Framework 4.1 Fluent API

查看:110
本文介绍了一对一,带有连接表和Entity Framework 4.1 Fluent API中的可选关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

再次使用无法更改的旧数据库,并使用Entity Framework 4.1和Fluent API来仅读取数据.

Again with a legacy database that cannot be changed and using Entity Framework 4.1 with the Fluent API to read data only.

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; }
}

我希望客户端有很多电话,但是电话应该只有一个可选的客户端. 注意:电话应仅包含0 | 1个客户端.我不要很多. 因此,我尝试了以下方法:

I want the Client to have many Phones, but the Phones should have only an optional Client. Note: Phones should have only 0|1 Client. I do NOT want a many to many. So I've tried the following:

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");
    });

我尝试了两种排列方式,通常会收到有关类型中的每个属性名称必须唯一"的错误.

I've tried a couple of permutations usually getting an error about "Each property name in a type must be unique."

感谢您的帮助.

使用答案进行编辑

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

Here are the modifications I made to the entity classes. It is possible to navigate from one Client to many Phones and from one Phone to one Client, but you must go through the ClientPhone join table.

[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
}

推荐答案

您无需在此处两次指定电话和客户端之间的关系.只能使用这样的一个.

you don't need to specify the relationship between phone and client two times here. Just use only one like this.

modelBuilder.Entity<Client>().HasMany(c => c.Phones).WithMany(i => i.Clients)
                .Map(t => t.MapLeftKey("PhoneID")
                    .MapRightKey("ClientID")
                    .ToTable("ClientPhone"));

您不需要模型来映射"ClientPhone"之类的关系表,因为EF会处理它.如果您有旧数据库,则可以像我的回答中那样自定义映射.正如@Ladislav Mrnka在数据库级别一对多关系中所说,您不想为关系保留单独的表.为此,

you do not need to have models to map relationship tables like "ClientPhone" because EF will take care of it .If you have a legacy database you can customize your mappings as in my answer. And as @Ladislav Mrnka said for one to many rel.ationship in database level you do not want to keep a separate table for the relationship. For that ,

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; }
}

这对于EF就足够了.它将使用 Phone 表中的 clientId 列创建两个表,以保持关系.

this will be enough with EF. It will create two tables with clientId column in Phone table to keep the relationship.

问题是您的遗留数据库中有一个单独的关系表.我认为遗留数据库是为多对多关系定义的.请再考虑两次域逻辑.

The problem is you have separate table for relationship in your legacy database.I think legacy database is defined for many-to-many relationship.Think twice your domain logic again.

如果要保持一对多关系,我可以在域级别定义多对多关系(电话中有很多客户端,并且客户在模型分类中有很多电话),然后在业务层中添加验证以仅保留一名客户来使用电话.

If you want to keep one-to-many relationship what I think is you can define in domain level many-to-many relationship (phone have many clients and client have many phones in model clases) and in you business layer add validations to keep only one client for a Phone.

这篇关于一对一,带有连接表和Entity Framework 4.1 Fluent API中的可选关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆