简体   繁体   English

实体框架(核心),多次引用同一张表但对象不同

[英]Entity Framework (Core), multiple refrences to the same table but different objects

I have an automotive part: 我有一个汽车零件:

CREATE TABLE dbo.Part (
    Id int IDENTITY(1,1) not null,
    PartNumber nvarchar(48) not null,
    Colour nvarchar(100) null,
    Height int null,
    -- etc
)

Automotive parts are often interchangeable. 汽车零件通常是可互换的。 You can replace 1 part on your car/truck with OEM part "A" or aftermarket part "B". 您可以将汽车/卡车上的1个零件替换为OEM零件“ A”或配件市场零件“ B”。

CREATE TABLE dbo.Interchanges (
    Part1 int not null,
    Part2 int not null,
    Notes nvarchar(500) not null,
)

ALTER TABLE dbo.Interchanges WITH CHECK ADD CONSTRAINT fk_Interchanges_Part1
FOREIGN KEY (Part1) REFERENCES dbo.Part (Id)

ALTER TABLE dbo.Interchanges WITH CHECK ADD CONSTRAINT fk_Interchanges_Part2
FOREIGN KEY (Part2) REFERENCES dbo.Part (Id)

Note: 1 part can be interchanged with many other parts, and interchanges are two-way in this case. 注意:1个部分可以与许多其他部分互换,在这种情况下,互换是双向的。

Now let's pretend I've two parts (part number A, and B), and they are interchanged with one another. 现在,假设我有两个部分(零件号A和B),并且它们彼此互换。

When I instantiate part A I'd like it to have a collection of Interchanges. 当我实例化A部分时,我希望它具有一组Interchanges。 In this case the collection would have one object. 在这种情况下,集合将只有一个对象。 That object would have the interchange notes and a part object instance whose part number is B. 该对象将具有交换注释和零件编号为B的零件对象实例。

Similarly, if I edit part B, it's collection would have an object which has the interchange notes and a part instance whose part number is A. 同样,如果我编辑零件B,则其集合中将有一个对象,该对象具有互换注释和零件实例,零件编号为A。

Is there an elegant way to model this? 有没有一种优雅的方式对此建模?

Is there a name for this pattern that I can Google? Google可以为这种模式命名吗?

With the SQL above when I load part A it has a ICollection (created with the Entity Framework Power Tools addon). 使用上面的SQL,当我加载部件A时,它具有一个ICollection(使用Entity Framework Power Tools插件创建)。 That interchange object has the interchange notes, an instance of Part B, and also an instance of Part A. 该交换对象具有交换注释,B部分的实例以及A部分的实例。

In the relational model there's no first-class way to model a Symmetric Relation , so you either have to handle it in application code, or store it as two separate rows (A,B, 'A and B are interchangable') and (B,A, 'A and B are interchangable') 在关系模型中,没有一流的方法来为对称关系建模,因此您要么必须在应用程序代码中对其进行处理,要么将其存储为两个单独的行(A,B,“ A和B可互换”)和(B ,A,“ A和B可互换”)

If you add rows for the inverse of each relation, then the EF model is simple, as Part only needs one Navigation Property. 如果为每个关系的倒数添加行,则EF模型很简单,因为零件仅需要一个导航属性。

Here's a Code First model version of what (I think) you are looking for: 这是您正在寻找的代码优先模型版本:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;

namespace ConsoleApp6
{
    public class Part
    {
        public int Id { get; set; }
        public string PartNumber { get; set; }
        public string Colour { get; set; }
        public int Height { get; set; }

        public virtual ICollection<Interchange> Interchanges { get; } = new HashSet<Interchange>();

    }

    public class Interchange
    {
        [Key]
        [Column(Order =1 )]
        public int FromPartId { get; set; }

        [Key]
        [Column(Order = 2)]
        public int ToPartId { get; set; }

        public virtual Part FromPart { get; set; }
        public virtual Part ToPart { get; set; }
    }



    class Db : DbContext
    {

        public DbSet<Part> Parts { get; set; }
        public DbSet<Interchange> Interchanges { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Part>()
                        .HasMany(p => p.Interchanges)
                        .WithRequired()
                        .HasForeignKey(i => i.FromPartId)
                        .WillCascadeOnDelete(false);

            base.OnModelCreating(modelBuilder);
        }


    }
    class Program
    {
        static void Main(string[] args)
        {
            Database.SetInitializer(new DropCreateDatabaseAlways<Db>());

            using (var db = new Db())
            {
                db.Database.Log = a => Console.WriteLine(a);

                var A = db.Parts.Create();
                A.PartNumber = "A";

                var B = db.Parts.Create();
                B.PartNumber = "B";

                A.Interchanges.Add(new Interchange() {  FromPart = A, ToPart = B });
                B.Interchanges.Add(new Interchange() { FromPart = B, ToPart = A });

                db.Parts.Add(A);
                db.Parts.Add(B);

                db.SaveChanges();
            }

            using (var db = new Db())
            {
                db.Configuration.LazyLoadingEnabled = true;
                db.Configuration.ProxyCreationEnabled = true;

                var A = db.Parts.Where(p => p.PartNumber == "A").Single();

                Console.WriteLine($"Part {A.PartNumber} has {A.Interchanges.Count()} Interchanges");

                Console.WriteLine($"Part {A.PartNumber} is interchangable with {A.Interchanges.First().ToPart.PartNumber}");
            }
                Console.ReadKey();
        }
    }
}

暂无
暂无

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

相关问题 实体框架Core 2中相同属性的跨域对象的行为不同 - Different behavior across domain objects for same properties in Entity Framework Core 2 实体框架 - 同一实体的不同代理对象。 并包含具有到同一目的地的多条路径的行为 - Entity Framework - Different proxy objects for the same entity. And Include behavior with multiple paths to same destination 实体框架核心 model 具有同一表的层次结构 - Entity Framework Core model with hierarchy of the same table 在 Entity Framework Core 中添加与同一个表具有多个一对一关系的实体时出现堆栈溢出 - Stack overflow when adding an entity with multiple one-to-one relationship with the same table in Entity Framework Core Entity Framework Core 与表的多重关系 - Entity Framework Core multiple relations to a table 实体框架| 一个表中的多个对象 - Entity Framework | Multiple Objects from one table 使用实体框架核心2在不同的受限上下文中存储对多个对象的引用 - Storing a Reference to multiple objects in a different bounded context using entity framework core 2 Entity Framework Core:如何将不同的对象实例映射到同一个实体? - Entity Framework Core: how to map different object instances to the same entity? Entity Framework Core 在同一个事务中使用具有不同连接字符串的多个上下文 - Entity Framework Core using Multiple Contexts with different connection strings in the same Transaction 实体框架对同一个表的多个引用 - Entity Framework multiple references to same table
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM