简体   繁体   English

自定义列上的一对多关系

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

I have two models that I'd like to specify a one-to-many relationship between, but I can't seem to get it to work.我有两个模型,我想在它们之间指定一对多的关系,但我似乎无法让它工作。 Here are the models:以下是模型:

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

As you can see, both class Apple and class Banana have a column in them called ThingId and that's how I'd like to join the associations together.如您所见, Apple类和Banana类中都有一个名为ThingId的列,这就是我希望将这些关联加入的方式。 This is a legacy DB so I can't change the column names.这是一个旧数据库,因此我无法更改列名。 However, when I run a query like this, I don't get an array of B objects back even though I know they exist.但是,当我运行这样的查询时,即使我知道它们存在,我也没有得到B对象的数组。

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

Any ideas on how I can get this to work properly using a custom column like this (preferably without fluent syntax since I prefer attributes, but not a big deal if that's necessary).关于如何使用这样的自定义列使其正常工作的任何想法(最好没有流畅的语法,因为我更喜欢属性,但如果有必要,这没什么大不了的)。

Thanks!谢谢!

Edit: The link in the answer below by Rafi did the trick.编辑: Rafi 下面的答案中的链接成功了。 Here's what I ending up using via the Fluent API.这是我最终通过 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);
}

Try modifying your data models as in the following example:尝试修改您的数据模型,如下例所示:

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

Update:更新:

If ThingId is not a primary key consider using GroupJoin as below:如果ThingId是不是主键可以考虑使用GroupJoin如下:

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

Given your scenario, we're going to have to set some few Constraints in order to get the relationship to work.鉴于您的情况,我们将不得不设置一些约束以使关系起作用。 In this case, each apple has a unique key called Id , which would be a feasible property to use as foreign key to Apple related entities.在这种情况下,每个苹果都有一个名为Idunique key ,这将是一个可行的属性,可用作Apple相关实体的外键。 But SQL does allow other columns to be used as foreign keys provided that they are unique for each row, which is Apple in your case.但是 SQL 确实允许将其他列用作外键,前提是它们对于每一行都是唯一的,在您的情况下是Apple

So to achieve this let's look at your given code:因此,为了实现这一点,让我们看看您给定的代码:

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

From your code, we'll have to make ThingId uniquer for every Apple .根据您的代码,我们必须使 ThingId 对每个Apple ThingId唯一的。 So let's configure that with Fluent API:所以让我们用 Fluent API 配置它:

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

Then, with continue to configure the one-to-many relationship with fluend API:然后,继续配置与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

An then your relationship will be set correctly.然后您的关系将被正确设置。


Conclusion结论

Let's recap, A ForeignKey has to be a unique key from the foreign entity.让我们回顾一下, ForeignKey必须是来自外部实体的唯一键。 I always recommend you to use FluentAPI for configuring your relationships, because you have control over many attributes of that relationship.我总是建议您使用 FluentAPI 来配置您的关系,因为您可以控制该关系的许多属性。

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

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