簡體   English   中英

實體框架相關表獲取和保存數據

[英]Entity Framework Related Tables Get and Save Data

我一直在NETSO中尋找一些答案-我對Entity Framework幾乎是個菜鳥..所以我對相關實體確實有些困惑..我正在使用C#,Winforms,Linq,EF6 ^(生成的反向DB類在DAL項目中)

我無法解決這個問題。 我有3個與第4個表相關的表-第4個表使用其他3個表中的PK_ID列-配置為外鍵,它們還構成了復合鍵(主鍵)。

我的原始ER圖來自油漆。

ER圖

我在EF查詢中需要做的是獲取多個數據綁定列綁定到列表視圖。

我想要的列是EnumerationCode,Part.Number,Part.Description。

我將使用ProdID(我將Products綁定到DropDown)作為這些附加值的獲取器。

因此,基本上,我要牢記這一點:從TernaryTable中選擇T在ENumTable.EnumID上加入EnumID,其中T.ProdID = myProdID,按EnumCode順序[從中選擇Part.Number,Part.Description從PartID = TernaryTable.PartID的部件中選擇)

我認為對於如何獲取此數據然后如何保存對數據的任何更改,可能有一個簡單的解決方案-但正如我所說的,我很迷惑。

我需要兩種方法,一種用於獲取數據,另一種用於保存對數據進行的任何更改。

我讀過了

使用Linq到實體從表和相關表中獲取記錄

實體框架linq查詢Include()多個子實體

但似乎我仍然對多重關系迷失了。

編輯

我認為在Haralds出色的答復之后,我需要並且可以發布更好的聲明以及真實的圖表!

更好的SQL圖

現在獲取表信息:

我想要MprnEnum.RefName,Part.PartNumber,Part.Name,Part.Description,其中ProductID = [Product.ID-我將提供的此ID]由MPRNENUM.RefName排序。 我希望能夠使用VS EF從數據庫生成的實體類對ProdPartEnum執行CRUD。

有20個RefName,每個產品都有許多EnumID,並且EnumID可以屬於許多產品,每個ProdEnum具有一個關聯的部分。 許多零件可以屬於許多ProdEnums

一個典型的表條目可能如下所示:ProdID = 1,EnumID = [1-20],PartID [1-1000]其中產品ID = 1,我們有20行EnumID,每行將有一個PartNumber。

如果需要,我可以發布更多詳細信息。

我的,這是一個奇怪的多對多對多!

通常情況下,設計如下:

  • 每個Product具有零個或多個Parts ,每個Part用於零個或多個Products (多對多ProductPart
  • 每個Product都有零個或多個Enumerations ,每個Enumeration由零個或多個Products (多對多ProductEnumeration
  • 每個Part都有零個或多個Enumerations ,每個Enumeration用於零個或多個Parts (多對多EnumerationPart

這將導致三個聯結表ProductPartProductEnumerationEnumerationPart

您選擇的設計只有一個連接表。

您確實意識到,在您的設計中,只要一個Product具有PartProductPart都具有相同的Enumeration ,不是嗎? product Enumerations數或其他Enumerations不能超過productParts數。 你不能有一個Product具有Part但不Enumerations

如果您真的想將數據庫限制在此范圍內,則可以使用以下類:

class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Junction> Junctions { get; set; }
}
class Part
{
    public int Id { get; set; }
    public int Number { get; set; }
    public string Description { get; set; }
    public virtual ICollection<Junction> Junctions { get; set; }
}
class Enumeration
{
    public int Id { get; set; }
    public int Code { get; set; }
    public virtual ICollection<Junction> Junctions { get; set; }
}

您的聯結表將如下所示:

public class Junction
{
    // foreign keys; composite primary key
    public int ProductId { get; set; }
    public int EnumId { get; set; }
    public int PartId { get; set; }

    public virtual Product Product { get; set; }
    public virtual Enumeration Enumeration { get; set; }
    public virtual Part Part { get; set; }
}

請注意:在實體框架中,非虛擬屬性表示表中的實際列。 虛擬屬性表示表之間的關系

您的DbContext將具有四個表:

class ManyDbContext : DbContext
{
    public DbSet<Product> Products { get; set; }
    public DbSet<Enumeration> Enumerations { get; set; }
    public DbSet<Part> Parts { get; set; }
    public DbSet<Junction> Junctions {get; set;}
}

最后,在OnModelCreating中,您必須指定設計:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    var junctionConfig = modelBuilder.Entity<Junction>();

    // composite primary key:
    junctionConfig.HasKey(junc => new { junc.ProductId, junc.PartId, junc.EnumId);

    // every junctionconfig has a mandatory foreign key to Product in ProductId
    // which represent a one-to-many (one Product has many Junctions)
    junctionConfig.HasRequired<Product>(junc => junc.Product)
        .WithMany(product => product.Junctions)
        .HasForeignKey<int>(junc => junc.ProductId);

    // every junctionconfig has a mandatory foreign key to Enumerations in EnumerationId
    // which represent a one-to-many (one Enumeration has many Junctions)
    junctionConfig.HasRequired<Enumeration>(junc => junc.Enumeration)
        .WithMany(enumeration => enumeration.Junctions)
        .HasForeignKey<int>(junc => junc.EnumId);

    // every junctionconfig has a mandatory foreign key to Pars in PartId
    // which represent a one-to-many (one Part has many Junctions)
    junctionConfig.HasRequired<Part>(junc => junc.Part)
        .WithMany(part => part.Junctions)
        .HasForeignKey<int>(junc => junc.PartId);

    base.OnModelCreating(modelBuilder);
}

回到您的問題

給定一個productId ,請給我具有該ProductIdProduct所有EnumerationCodesPart.NumberPart.Description記錄

當使用實體框架時,人們傾向於對外鍵執行聯接,而不是在表中使用虛擬屬性,這會使事情變得更加復雜。

如果您使用虛擬屬性,則查詢將非常簡單且直觀:

var result = dbContext.Junctions
    .Where(junction => junction.ProductId == productId)
    .Select(junction => new
    {
        EnumerationCode = junction.Enumeration.EnumerationCode,
        PartNumber = junction.Part.Number,
        PartDescription = junction.Part.Description,
    });

實體框架足夠智能,可以檢測到需要哪些聯接。

如果您確實想進行聯接,則必須對三個表進行聯接。 這樣的連接看起來很可怕:

var x = dbContext.Junctions                              // from all junctions
    .Where(junction => junction.ProductId == productId)  // take only the ones with productId

                                                          // The first join:
    .Join(dbContext.Parts,                                // Join with Parts
        junction => junction.PartId,                      // from the Junction take the PartId,
        part => part.Id,                                  // from the Parts take the Id
        (junction, part) => new                           // when they match make one new object
        {                                                 // containing some properties
            EnumerationId = junction.EnumId,
            PartNumber = part.Number,
            PartDescription = part.Description,
        })

                                                          // Second Join
        .Join(dbContext.Enumerations,                     // Join with enumerations
            junction => junction.EnumerationId,           // from the 1st join result take EnumerationId
            enumeration => enumeration.Id,                // from enumerations take Id
            (junction, enumeration) => new                // when they match make one new object
            {                                             // containing your desired properties
                EnumerationCode = enumeration.Code,
                PartNumber = junction.PartNumber,
                PartDescription = junction.PartDescription,
            });

您很幸運,不需要產品的說明。 如果要使用虛擬屬性,這將很容易:

var result = dbContext.Junctions
    .Where(junction => junction.ProductId == productId)
    .Select(junction => new
    {
        Description = junction.Product.Description,
        EnumerationCode = junction.Enumeration.EnumerationCode,
        PartNumber = junction.Part.Number,
        PartDescription = junction.Part.Description,
    });

由您來編寫一個包含四個表的聯接。 查看區別並確定從現在開始要使用哪種方法。

暫無
暫無

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

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