【问题标题】:Design pattern or algorithim for updating tree structure represented by several layers of entities用于更新由多层实体表示的树结构的设计模式或算法
【发布时间】:2019-02-05 19:07:31
【问题描述】:

有一个案例,我的目标表有几个与 FK 相关的“层”。

Root
    |__A
        |__B
            |__C
                |__D

我正在从一个平面文件中导入一些数据,并将结果投影到一组非常相似的 POCO 对象中。从那里我需要从这些 POCO 对象中进行选择并进入实体。问题是如何最好地更新实体,因为每个级别都可以是新的或已经存在并且需要更新。

例如,根对象本身可能已经创建,但不包含 A,因此必须创建 A,然后添加其依赖对象。

类似地,Root 和 A 一样可能已经存在,但它的依赖 B 不存在。 每个级别都有需要更新的特定字段(如果它们已经存在)。

【问题讨论】:

    标签: c# algorithm entity-framework design-patterns


    【解决方案1】:

    您的数据库

    我假设您的层中存在一对多关系:每个 Root 都有零个或多个 As,每个 A 使用外键完全属于一个 Root。每个 A 都有零个或多个 B,每个 B 恰好属于一个 A,使用外键等。

    在实体框架中,您将拥有如下内容:

    class Root
    {
        public int Id {get; set;}
        ... // other properties
    
        // every Root has zero or more As (one-to-many):
        public virtual ICollection<A> As {get; set;}
    }
    class A
    {
        public int Id {get; set;}
        ... // other properties
    
        // every A belongs to exactly one Root, using foreign key
        public int RootId {get; set;}
        public virtual Root Root {get; set;}
    
        // every A has zero or more Bs:
        public virtual ICollection<B> Bs {get; set;}
    }
     class B
    {
        public int Id {get; set;}
        ... // other properties
    
        // every B belongs to exactly one A, using foreign key
        public int AId {get; set;}
        public virtual A A {get; set;}
    
        // every B has zero or more Cs:
        public virtual ICollection<C> Cs {get; set;}
    }
    etc.
    

    在实体框架中,表的列由非虚拟属性表示。虚拟属性表示表之间的关系(一对多、多对多)

    您的文件

    您提到可能是您已经从文件中读取了 Root1 并与其他孩子再次读取了 Root1。看来您的文件是扁平的:

    Root1, A1, B1, ...
    Root1, A1, B2, ...
    Root1, A2, B3, ...
    Root2, A3, B4, ...
    Root1, A4, B5, ...
    

    显然你有一个读取文件“行”的功能:

    class Line
    {
        public Root Root {get; set;}
        public A A {get; set;}
        public B B {get; set;}
        ...
    }
    
    IEnumerable<Line> ReadLines(...) {...}
    

    填充数据库

    void FillDatabase(IEnumerable<Line> lines)
    {
        // convert the lines into a sequence or Roots with their As,
        // with their Bs, with their Cs, ...
        IEnumerable<Root> roots = lines.GroupBy(line => line.Root,
            (root, linesOfThisRoot) => new Root
            {
                Name = root.Name,
                ... other root properties
                As = linesOfThisRoot.GroupBy(line => line.A,
                (a, linesWithRootAndA) => new A
                {
                    Name = a.Name,
                    ... other a properties
                    Bs = linesWithRootAndA.GroupBy(line => line.B,
                         (b, linesWithRootAB) => new B
                         {
                            ... B properties
                            Cs = linesWithRootAB.GroupBy(line => line.C,
                            {
                               etc.
                            })
                            .ToList(),
                        })
                        .ToList(),
                   })
                   .ToList(),
                })
                .ToList();
            });
        using (var dbContext = new MyDbContext()
        {        
            dbContext.Roots.AddRange(roots.ToList());
            dbContext.SaveChanges();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-02
      • 1970-01-01
      • 2012-08-21
      • 1970-01-01
      • 2011-04-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多