簡體   English   中英

實體框架樹結構

[英]Entity Framework tree structure

我有一個名為Field的實體,它看起來像:

Field.cs

class Field
{
    public int Id { get; set; }
    public string Name { get; set; }
}

因此字段看起來像一個簡單的列表,如下所示:

1 : First Name
2 : Last Name
3 : Gender
4 : Passport
5 : Driver License
6 : Issued
7 : Expired

對於每個稱為Batch的實體,我想要一個任意的字段樹,可能看起來像這樣:

第一批

     First Name   |      Last Name      |       Passport         |      Gender
                                        |  Issued    |   Expired |

或這個:

第二批

     First Name   |      Last Name      |      Gender      |      Driver License    |
                                                           |  Issued    |   Expired |

或其他任何字段樹,其中用戶將為每個字段鍵入不同的值(例如,某些字段只是標題,例如Passport)

因此,我的字段只是可以重用的元素列表,基於批處理在它們之間具有任何類型的關系。 我的想法是使批處理實體如下所示:

Batch.cs

class Batch 
{
     public int Id { get; set; }
     public string Fields { get; set; }
     // other data...
}

其中fields是“ First Batch”的JSON樹,如下所示:

{ 1, 2, 4: { 6, 7 }, 3 }

第二批是這樣的:

{ 1, 2, 3, 5: { 6, 7 } }

批次甚至可以具有如下更深層的嵌套字段:

|             Passport             |
|     Issued      |     Expired    |
| Month  | Year   | Month  | Year  |   

這是在EF中存儲這樣的關系的最佳方法嗎? 我應該避免使用JSON字段並對數據進行規范化嗎? 如果是這樣,我將如何使用EF模型優先保存任意樹關系?

我建議您創建兩個類文檔,並像這樣聲明

class Batch
{
 public int BatchId { get; set; }
 public string BachFirstName{ get; set; }
 public string BachLastName{ get; set; }
 public string BachGender{ get; set; }
 public Document BachDocument{ get; set; }
}

class Document
{
 public int DocId { get; set; }
 public string DocDesignation{ get; set; }
 public State DocState{ get; set; }
}


class State
{
 public int Id { get; set; }
 public string StateDesignation{ get; set; }
 public date StateDate{ get; set; }
}

如果要使其動態,則需要使用像這樣的鍵值表。

namespace ConsoleApplication1
{
    class Db : DbContext
    {
        public DbSet<User> Users { get; set; }
        public DbSet<Batch> Batches { get; set; }
    }

    class User
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int UserId { get; set; }
        public virtual List<Batch> Batches { get; set; }
    }

    class Batch
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int BatchId { get; set; }
        [Required, MaxLength(256)]
        public string Key { get; set; }
        [MaxLength(512)]
        public string Value { get; set; }
        public virtual List<Batch> Children { get; set; }
    }

    class Initializer : DropCreateDatabaseAlways<Db>
    {
        protected override void Seed(Db context)
        {
            var user = new User();
            context.Users.Add(user);
            user.Batches = new List<Batch>();
            user.Batches.AddRange(new List<Batch>
            {
                new Batch {Key = "First Name", Value = "John"},
                new Batch {Key = "Last Name", Value = "Smith"},
                new Batch {Key = "Passport", Children = new List<Batch>
                {
                    new Batch {Key = "Issued", Value = "2014-02-03"},
                    new Batch {Key = "Expired", Value = "2015-02-03"},
                }}
            });
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Database.SetInitializer(new Initializer());
            using (var db = new Db())
            {
                Console.WriteLine(JsonConvert.SerializeObject(db.Batches.ToList(), Formatting.Indented));
                Console.ReadLine();
            }
        }
    }
}

該表的生成Schema

CREATE TABLE [dbo].[Batches](
    [BatchId] [int] IDENTITY(1,1) NOT NULL,
    [Key] [nvarchar](256) NOT NULL,
    [Value] [nvarchar](512) NULL,
    [Batch_BatchId] [int] NULL,
    [User_UserId] [int] NULL,
 CONSTRAINT [PK_dbo.Batches] PRIMARY KEY CLUSTERED 
(
    [BatchId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Batches]  WITH CHECK ADD  CONSTRAINT [FK_dbo.Batches_dbo.Batches_Batch_BatchId] FOREIGN KEY([Batch_BatchId])
REFERENCES [dbo].[Batches] ([BatchId])
GO

ALTER TABLE [dbo].[Batches] CHECK CONSTRAINT [FK_dbo.Batches_dbo.Batches_Batch_BatchId]
GO

ALTER TABLE [dbo].[Batches]  WITH CHECK ADD  CONSTRAINT [FK_dbo.Batches_dbo.Users_User_UserId] FOREIGN KEY([User_UserId])
REFERENCES [dbo].[Users] ([UserId])
GO

ALTER TABLE [dbo].[Batches] CHECK CONSTRAINT [FK_dbo.Batches_dbo.Users_User_UserId]
GO

其中[User_UserId]不是NULL根批次和[Batch_BatchId]不是NULL為嵌套的。 遍歷這棵樹取決於您和您的業務邏輯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM