实体框架流畅API映射问题

本文关键字:映射 问题 API 框架 实体 | 更新日期: 2023-09-27 18:07:17

如何配置三个表之间的关系以获得所有相关数据?

我有以下模型(和数据库中相同的表):

public class Client 
{
  public Guid ClientId { get; set; }
  public string FirstName { get; set; }
  public virtual ClientCard ClientCard { get; set; }
}
public class Card
{
  public Guid CardId { get; set; }
  public string Number { get; set; }
  public virtual ClientCard ClientCard { get; set; }
}
public class ClientCard
{
  public Guid ClientCardId { get; set; }
  public Guid CardId { get; set; }
  public Guid ClientId { get; set; }
  public virtual Client Client { get; set; }
  public virtual Card Card { get; set; }
}

和下面的OnModelCreating方法:

protected override void OnModelCreating(DbModelBuilder builder)
    {
        builder.Conventions.Remove<PluralizingTableNameConvention>();
        ...
        builder.Entity<ClientCard>()
            .HasKey(x => x.ClientCardId);
        builder.Entity<ClientCard>()
            .HasRequired(x => x.Client)
            .WithRequiredPrincipal(x => x.ClientCard);
        builder.Entity<ClientCard>()
            .HasRequired(x => x.Card)
            .WithRequiredPrincipal(x => x.ClientCard);
        base.OnModelCreating(builder);
    }

但是返回的结果没有相关数据。为什么?

实体框架流畅API映射问题

对于您的代码,请尝试这样做:

public class Client 
{
  public Guid ClientId { get; set; }
  public string FirstName { get; set; }
  public virtual ICollection<ClientCard> ClientCard { get; set; }
}
public class Card
{
  public Guid CardId { get; set; }
  public string Number { get; set; }
  public virtual ICollection<ClientCard> ClientCard { get; set; }
}
public class ClientCard
{
  public Guid ClientCardId { get; set; }
  public Guid CardId { get; set; }
  public Guid ClientId { get; set; }
  public virtual Client Client { get; set; }
  public virtual Card Card { get; set; }
}

和映射:

    builder.Entity<Client>()
           .HasKey(t => t.ClinetID);
    ....
    builder.Entity<Client>()
           .HasMany(a => a.ClientCard)
           .WithRequired(p => p.Client)
           .HasForeignKey(p => p.ClientID);

    ....
    builder.Entity<Card>()
           .HasMany(a => a.ClientCard)
           .WithRequired(p => p.Card)
           .HasForeignKey(p => p.CardID);

但是我认为最好的方法是为每个实体创建一个单独的地图文件

现在我使用以下模型:

public class Client 
{
   public Guid ClientId { get; set; }
   public string FirstName { get; set; }
   public Guid? CardId { get; set; }
   public virtual Card Card { get; set; }
}
public class Card
{
   public Guid CardId { get; set; }
   public string Number { get; set; }
   //public virtual Client Client { get; set; }
}

和以下OnModelCreating方法:

protected override void OnModelCreating(DbModelBuilder builder)
{
        builder.Conventions.Remove<PluralizingTableNameConvention>();
        ... 
        builder.Entity<Client>()
            .HasOptional(x => x.Card)
            //.WithOptionalPrincipal(x=> x.Client) 
            //or
            //.WithOptionalDependent(x=> x.Client)
            ;
        base.OnModelCreating(builder);
}

所有客户端返回相关数据(如果存在)。但是,如果我想获得与卡对象和uncomment public virtual Client Client { get; set; }和WithOptionalPrincipal/WithOptionalDependent相关的数据,我总是得到这些SqlException:"无效列名'Client_ClientId'"(如果WithOptionalPrincipal使用)或"无效列名'Card_CardId'"(如果WithOptionalDependent使用)

我终于找到解决办法了。

首先,我从Client类中删除了CardId。其次,我已经改变了我的OnModelCreating方法:

protected override void OnModelCreating(DbModelBuilder builder)
    {
        builder.Conventions.Remove<PluralizingTableNameConvention>();
        ...
        builder.Entity<Client>()
            .HasOptional(x => x.Card)
            .WithOptionalDependent(x => x.Client)
            .Map(x => x.MapKey("CardId"))
            .WillCascadeOnDelete(false);
        builder.Entity<Card>()
            .HasOptional(x => x.Client)
            .WithOptionalPrincipal(x => x.Card)
            .WillCascadeOnDelete(false);
        base.OnModelCreating(builder);
    }