簡體   English   中英

將 2 個表映射到實體框架中的單個實體

[英]Mapping 2 tables to single entity in Entity Framework

我希望你能幫助我。

我在數據庫中有 2 個表:Bill 和 BillItem。 這些表在數據庫中配置為一對一關系,其中 bill 是主表,而 BillItem 是依賴表

表 Bill 的結構:

Int BillId (PK)
Int BillTypeId Not Null
Varchar(5) Usr Not Null
DateTime Tm Not Null

表 BillItem 的結構:

Int BillItemId (PK)
Int ItemId Not Null 
Varchar(5) Usr Not Null
DateTime Tm Not Null

我想使用 Fluent API 和 Entity Framework 4.1 Code First 方法將這兩個表映射到單個 POCO 類中

我還想配置表列名稱以在 POCO 類中使用不同的屬性名稱(即 Id 而不是 BillId,User 而不是 Usr)

這是一個遺留數據庫,我無法修改它的任何對象。

怎樣才能做到這一點?

謝謝你們。

結果類應該是(如果可以的話):

public int Id {get;set;}
public int BillTypeId {get;set;}
public int ItemId {get;set;}
public string User {get;set;}
public string User1 {get;set;}
public DateTime Tm {get;set;}
public DateTime Tm1 {get;set;}

對於重命名列,這很容易:

[Table("SomeHorribleTableName")]
    public class MyNiceTableName
    {
        [Column("Usr")]
        public string User { get; set; }
    }

在這里,我也重命名了實體。無需保留可怕的表名。 關於將 2 個表映射到 1 個實體。我認為這是不可能的。 請參閱此處: 將數據從 2 個表映射到 1 個實體 - 實體框架 4

流線型:

public class Bill
    {
        public int ID { get; set; }
        public int BillTypeID { get; set; }
        public string UserName { get; set; }
        public DateTime Time { get; set; }
    }

    public class BillItem
    {
        public int ID { get; set; }
        public int ItemID { get; set; }
        public string UserName { get; set; }
        public DateTime Time { get; set; }
    }

    internal class BillMap : EntityTypeConfiguration<Bill>
    {
        public BillMap()
        {
            ToTable("Bills");
            HasKey(x => x.ID);
            Property(x => x.ID).HasColumnName("BillId");
            Property(x => x.BillTypeID).IsRequired().HasColumnName("BillTypeId");
            Property(p => p.UserName).IsRequired().HasColumnName("Usr");
            Property(x => x.Time).IsRequired().HasColumnName("Tm");
        }
    }

    internal class BillItemMap : EntityTypeConfiguration<BillItem>
    {
        public BillItemMap()
        {
            ToTable("BillItems");
            HasKey(x => x.ID);
            Property(x => x.ID).HasColumnName("BillItemId");
            Property(x => x.ItemID).IsRequired().HasColumnName("ItemId");
            Property(p => p.UserName).IsRequired().HasColumnName("Usr");
            Property(x => x.Time).IsRequired().HasColumnName("Tm");
        }
    }

這可能是我能做的最好的了。 至於處理兩個表中的 Usr 列,這可能是您應該在自己的控制器類/業務邏輯層中處理的事情。

還有一件事:對於上面的配置類.. 在您的 DbContext 中調用它們,如下所示:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Configurations.Add(new BillMap());
    modelBuilder.Configurations.Add(new BillItemMap());
}

我認為您可以使用實體拆分功能來實現這一點,但您需要使用一些數據注釋(無 esacpe):
警告我還沒有嘗試過這種方法,但它可能會起作用,如果您喜歡,請檢查一下首先:使用HasColumnName數據注釋對屬於您的單域模型類中的 BillItem 表的屬性進行注釋。
第二:使用此代碼示例

public class YourSingleModelClassNameConfiguration : EntityTypeConfiguration<YourSingleModelClassName> {
    public YourSingleModelClassNameConfiguration() {

        ToTable("Bill"); Property(param => param.Id).IsRequired().HasColumnName("BillId");

        // NOW REPEAT THAT FOR ALL BILL PROPERTIES WITH YOUR REQUIRED ATTRIBUTES (ISREQUIRED OR NOT, LENGTH ...)

        // NOW THE PROPERTIES YOU NEED TO MAP TO THE BILL ITEMS TABLE GOES INTO THE MAP FUNCTION
        Map(
        param =>
            { param.Properties(d => new {d.ItemId, d.User1}); m.ToTable("BillItem");
            }
        );

        // DON'T FORGET TO MENTION THE REST OF THE PROPERTIES BELONGING TO THE BillItem TABLE INSIDE THE PROPERTIES METHOD IN THE LAST LINE.

    }
}

對於這個問題,你可以很容易地做到這一點,你有 2 個選擇。 第一種是使用實體框架映射類(將多個表映射到實體框架中的單個實體類)。

第二種選擇是手動進行: 2 個表必須遵循的限制是 1 必須是強表,而第二個必須是弱表(通過這樣做,您應該只有從強表到弱)否則,這將不起作用,因為結果將是對象的集合,然后您需要確定第一個對象是否是您需要的對象,而不是其他對象。

如果您想使用稍微快一點的方法,我建議您使用自己的邏輯來映射 POCO 對象。 創建 2 個將與數據庫表映射並從服務對象構建對象的類。

這種方法很好,因為生成的 LINQ 查詢不會使用 INNER JOINS,這使得它更快。 但加入應該從你身邊保持。

例子

int i=0;
// this 2 refer to the 2 different mapped tables in your context database
var pbdata = _pbdata.GetSingle(p=>p.StrongTableID == StrongTableID);
var pb = _pb.GetSingle(p=>p.WeakTableID == pbdata.WeakTableID);
// you can see that i am looking for the StrongTableID in order to select the entity value

// this is optional but usefull! you can do the
// "copy" inside a function where in future if the 
// object changes, you can update easily
ObjectComposite.Map(body, ref pb, ref pbdata);

// the following proccess needs to be done like this...
// first save the value in the weak object so 
// the WeakTableID is recorded
// UPDATE: maybe these 2 should go into a transact for more security... but... ok...
Save(pb);
i += this.unitOfWork.Save();
pbdata.ProfessionalBodyID = pb.ProfessionalBodyID;

// once the values for the second objects are set, save it all again.
Save(pbdata);
i += this.unitOfWork.Save();
return i > 0 ? true : false;

這種方法更快,但您需要自己控制一切。 好消息是,您可以在這里映射任意數量的表格

希望能幫助到你!

暫無
暫無

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

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