EF Core中带有复合键的外键 [英] Foreign key with composite key in EF Core

查看:444
本文介绍了EF Core中带有复合键的外键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下类:

    public class ProductAttribute 
    {
        public Guid ProductId { get; set; }

        public Guid AttributeId { get; set; }

        public List<ProductAttributeValue> Values { get; set; }

        public object[] GetKeys()
        {
            return new object[] {ProductId, AttributeId};
        }
    }

    public class Product
    {
        public Guid Id { get; set; }

        public string Name { get; set; }
    }

    public class Attribute
    {
        public Guid Id { get; set; }

        public string Name { get; set; }
    }

    public class ProductAttributeValue
    {
        public Guid Id { get; set; }

        public string Name { get; set; }
    }

在原始情况下,Product和Attribute是AggregateRoot,所以我想跳过属性参考。值是一个简单的实体,但是您需要在我的ProductAttribute类中将其作为列表引用,因为您看到该类具有复合键。但是我想要在ProductAttribute
和ProductAttributeValue之间与级联删除建立必要的关系。

In origin case Product and Attribute are AggregateRoot so I want skip navigate that by property references. Value is a simple entity but I need that as list reference in my ProductAttribute class as you see that class have composite key. But I want a required relationship with cascade delete between ProductAttribute and ProductAttributeValue.

该项目是外部模块,所以我流畅的API配置是扩展,在目标应用程序DbContext OnModelCreating中调用。我应该配置每个属性,否则其他引用将不起作用。

This project is external module, so my fluent API configurations are extension which called in target app DbContext OnModelCreating. I should config every properties and references else didn't work.

        builder.Entity<ProductAttribute>(b =>
        {
            b.ToTable("ProductAttributes");

            b.HasKey(x => new {x.ProductId, x.AttributeId});

            //I should config ProductAttributeValue one-to-many manually here
        }

        builder.Entity<Product>(b =>
        {
            b.ToTable("Products");

            b.HasKey(x => x.Id);
        }

        builder.Entity<Attribute>(b =>
        {
            b.ToTable("Attributes");

            b.HasKey(x => x.Id);
        }

        builder.Entity<ProductAttributeValue>(b =>
        {
            b.ToTable("ProductAttributeValues");

            b.HasKey(x => x.Id);

            //I should config ProductAttribute many-to-one manually here
        }

如何为ProductAttribute实体配置Fluent API以通过这种情况?

How can you configure your Fluent API for ProductAttribute entity to passing this scenario?

推荐答案

为了根据需要配置所需的关系并进行级联删除,可以在<$ c $中使用以下内容c> ProductAttribute 实体配置块:

In order to configure the desired relationship as required and cascade delete, you can use the following inside the ProductAttribute entity configuration block:

b.HasMany(e => e.Values)
    .WithOne()
    .IsRequired();

IsRequired 就足够了,因为按照惯例,级联删除为必需关系打开,为可选关系关闭。当然,如果需要,您可以添加 .OnDelete(DeleteBehavior.Cascade)-这是多余的,但不会造成伤害。

IsRequired is enough because by convention cascade delete is on for required and off for optional relationships. Of course you can add .OnDelete(DeleteBehavior.Cascade) if you want - it will be redundant, but won't hurt.

请注意,应在单个位置配置关系。因此,请在 ProductAttribute ProductAttributeValue 中执行此操作,但不要同时在两者中进行(容易出错,可能会导致意外的冲突或覆盖配置

Please note that the relationships should be configured in a single place. So do it either in ProductAttribute or ProductAttributeValue, but never in both (error prone, may cause unexpected conflicting or overriding configuration issues).

为完整起见,这是您可以在 ProductAttributeValue 配置中配置相同内容的方法(要求显式提供 HasOne 泛型类型参数(由于缺少导航属性):

For completeness, here is how you can configure the same inside ProductAttributeValue configuration (requires explicitly providing the HasOne generic type argument due to the lack of navigation property):

b.HasOne<ProductAttribute>()
    .WithMany(e => e.Values)
    .IsRequired();

这篇关于EF Core中带有复合键的外键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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