繁体   English   中英

自定义列上的一对多关系

[英]One-to-many relationship on custom columns

我有两个模型,我想在它们之间指定一对多的关系,但我似乎无法让它工作。 以下是模型:

    public class Apple
    {
        public int Id { get; set; }
        public int ThingId { get; set; }

        public List<Banana> Bananas { get; set; }
    }
    public class Banana
    {
        public int Id { get; set; }
        public int ThingId { get; set; }
 
        [ForeignKey("ThingId")]
        public Apple Apple { get; set; }
    }

如您所见, Apple类和Banana类中都有一个名为ThingId的列,这就是我希望将这些关联加入的方式。 这是一个旧数据库,因此我无法更改列名。 但是,当我运行这样的查询时,即使我知道它们存在,我也没有得到B对象的数组。

var thing = _context.Apples.Include(a => a.Bananas).FirstOrDefault();
// thing - properly populated but the "Bananas" association is null

关于如何使用这样的自定义列使其正常工作的任何想法(最好没有流畅的语法,因为我更喜欢属性,但如果有必要,这没什么大不了的)。

谢谢!

编辑: Rafi 下面的答案中的链接成功了。 这是我最终通过 Fluent API 使用的内容。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Banana>()
        .HasOne(b => b.Apple)
        .WithMany(a => a.Bananas)
        .HasForeignKey(a => a.ThingId)
        .HasPrincipalKey(b => b.ThingId);
}

尝试修改您的数据模型,如下例所示:

public class Apple
{
    public int Id { get; set; }
    public List<Banana> Bananas { get; set; }
}

public class Banana
{
    public int Id { get; set; }

    [ForeignKey("Apple")]
    public int AppleId { get; set; }

    public Apple Apple { get; set; }
}

更新:

如果ThingId是不是主键可以考虑使用GroupJoin如下:

_context.Apples.GroupJoin(
  bana_context.Bananas,
  apple => apple.ThingId,
  banana => banana.ThingId,
  (apple, bananas) =>
  {
    apple.bananas = bananas.ToList();
    return apple;
  }
)

鉴于您的情况,我们将不得不设置一些约束以使关系起作用。 在这种情况下,每个苹果都有一个名为Idunique key ,这将是一个可行的属性,可用作Apple相关实体的外键。 但是 SQL 确实允许将其他列用作外键,前提是它们对于每一行都是唯一的,在您的情况下是Apple

因此,为了实现这一点,让我们看看您给定的代码:

public class Apple
{
    public int Id { get; set; }
    public int ThingId { get; set; }
    public List<Banana> Bananas { get; set; }
}
public class Banana
{
    public int Id { get; set; }
    public int ThingId { get; set; }
    public Apple Apple { get; set; }
}

根据您的代码,我们必须使 ThingId 对每个Apple ThingId唯一的。 所以让我们用 Fluent API 配置它:

modelBuilder.Entity<Apple>()
    .HasIndex(ux=>ux.ThingId)
    .IsUnique()
    .Isclustered(false);

然后,继续配置与fluend API的一对多关系:

modelBuilder.Entity<Apple>()
   .HasMany(apple => apple.Bananas)
   .WithOne(banana => banana.Apple)
   .HasForeignKey(banana => banana.ThingId)
   .Isrequired(false)
   .OnDelete(DeleteBehavior.Cascade); // You can set the DeleteBehavior here

然后您的关系将被正确设置。


结论

让我们回顾一下, ForeignKey必须是来自外部实体的唯一键。 我总是建议您使用 FluentAPI 来配置您的关系,因为您可以控制该关系的许多属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM