zoukankan      html  css  js  c++  java
  • EF Core – Many to Many

    前言

    Many to many 是 EF Core 5.0 才开始有的, 以前都用 2 个 1-n 来实现的.

    由于它比 1-n 复杂, 所以有必要写一遍来记入一下.

    参考:

    Relationships

    Property bag entity types

    Without Fluent API

    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
    
        public ICollection<Tag> Tags { get; set; }
    }
    
    public class Tag
    {
        public string TagId { get; set; }
    
        public ICollection<Post> Posts { get; set; }
    }

    在完全没有 Fluent API 配置下, 只要 2 个 class 有关系的 collection 就可以表达 n-n 了.

    它会自动创建一个 Join entity type configuration, 就可以生产 migration 了. 

    为什么是 CategoryProduct 而不是 ProductCategory 呢? 

    它是按 class name A-Z 排序的. C 比 P 前面, 所以就是 CategoryProduct.

    Joining relationships configuration (Dictionary)

    想自己配置 Join entity type configuration 也是 ok 的.

    modelBuilder.Entity<Category>()
        .HasMany(e => e.Products)
        .WithMany(e => e.Categories)
        .UsingEntity<Dictionary<string, object>>(
            j => j
                .HasOne<Product>()
                .WithMany()
                .HasForeignKey("ProductId")
                .OnDelete(DeleteBehavior.Cascade),
            j => j
                .HasOne<Category>()
                .WithMany()
                .HasForeignKey("CategoryId")
                .OnDelete(DeleteBehavior.Cascade),
            j =>
            {
                j.ToTable("CategoryProduct");
                j.Property<int>("Id").HasColumnName("CategoryProductId");
                j.HasKey("Id").IsClustered(false);
                j.HasIndex("ProductId", "CategoryId").IsUnique().IsClustered(true);
    
                j.HasAnnotation("AuditTrail", null);
                j.Property<string>("CreatedBy");
                j.Property<DateTimeOffset>("DateCreated");
            }
        );

    第 3 个 parameter 是配置 Join Entity. 注意这里用的是 Dictionary 来表示 Join Entity 而不是 class, 这个做法比较适合那种在 application level 不会用到这个 join entity 的情况.

    如果需要用到的话, 那么应该用下面这个方式.

    Joining relationships configuration (Class)

    public class CategoryProduct
    {
        public int Id { get; set; }
        public int ProductId { get; set; }
        public Product Product { get; set; } = null!;
        public int CategoryId { get; set; }
        public Category Category { get; set; } = null!;
        public string CreatedBy { get; set; } = "";
        public DateTimeOffset DateCreated { get; set; }
    }

    没有太大的区别, 就是定义多一个 class 就 ok 了.

    modelBuilder.Entity<Category>()
        .HasMany(e => e.Products)
        .WithMany(e => e.Categories)
        .UsingEntity<CategoryProduct>(
            j => j.HasOne(e => e.Product)
                .WithMany()
                .HasForeignKey(e => e.ProductId)
                .OnDelete(DeleteBehavior.Cascade),
            j => j.HasOne(e => e.Category)
                .WithMany()
                .HasForeignKey(e => e.CategoryId)
                .OnDelete(DeleteBehavior.Cascade),
            j =>
            {
                j.ToTable("CategoryProduct");
                j.HasKey(e => e.Id).IsClustered(false);
                j.HasIndex(e => new { e.CategoryId, e.ProductId }).IsUnique().IsClustered(true);
            }
        );
  • 相关阅读:
    SVM+HOG特征训练分类器
    数字图像处理的基本原理和常用方法
    c++中二进制和整数转化
    目标检测——HOG特征
    相似图片搜索的原理和实现——颜色分布法
    测试文本文件大小
    Direct2D 图形计算
    Direct2D 如何关闭抗锯齿
    MFC窗口显隐
    CISP/CISA 每日一题 22
  • 原文地址:https://www.cnblogs.com/keatkeat/p/15685162.html
Copyright © 2011-2022 走看看