2014-01-30 92 views
1

我有一個數據庫生成的應用程序,我不能修改(我可以添加表,視圖等,但我不能修改現有的表,向他們添加列) 。我使用一個Web應用程序工作,該應用程序使用BreezeJS通過OData協議允許Web應用程序的客戶端部分查詢數據。EF Code First現有的數據庫,映射一對多

Measurement表具有以下結構:

MeasurementId INT 
DeviceId INT FOREIGN KEY REFERENCES Devices (DeviceId) 
Name VARCHAR, 
PRIMARY KEY (MeasurementId) 

我需要的是增加可空ParentId自我參照的外鍵,因爲我不能修改現有的表,我創建了新的,Measurement_Parent

MeasurementId INT FOREIGN KEY REFERENCES Measurements (MeasurementId), 
ParentId INT FOREIGN KEY REFERENCES Measurements (MeasurementId), 
PRIMARY KEY (MeasurementId) 

我有以下實體:

public partial class Measurement 
{ 
    public Measurement() 
    { 
     this.Children = new List<Measurement>(); 
    } 

    public Int32 MeasurementId { get; set; } 

    public virtual Measurement Parent { get; set; } 

    public Int32 DeviceId { get; set; } 

    public virtual Device Device { get; set; } 

    public String Name { get; set; } 

    public virtual ICollection<Measurement> Children { get; set; } 
} 

現在是棘手的部分。我嘗試了許多不同的方法來獲得這個工作,但沒有成功。我的實體當前EntityTypeConfiguration看起來是這樣的:

// Primary Key 
this.HasKey(m => m.MeasurementId); 

// Table & Column Mappings 

this.Property(t => t.MeasurementId) 
    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); 

// Table & Column Mappings 
this.ToTable("Measurement"); 
this.Property(m => m.MeasurementId); 
this.Property(m => m.DeviceId); 
this.Property(m => m.Name); 

// Relationships 

// Each measurement references device performing the measurement. 
this.HasRequired(d => d.Device) 
    .WithMany(m => m.Measurements) 
    .HasForeignKey(d => d.DeviceId); 

// Each measurement can have optional parent. 
this.HasOptional(measurement => measurement.Parent) 
    .WithMany() // .WithMany(measurement => measurement.Children) ?? 
    .Map(m => 
    { 
     m.MapKey("ParentId"); 
     m.ToTable("Measurement_Parent"); 
    }); 

很不幸,這讓我奇怪的錯誤而載入我的應用程序:

Metadata query failed for: api/EDW/Metadata; The specified table 'Measurement_Parent' was not found in the model. Ensure that the table name has been correctly specified. 

我不知道爲什麼會出現這種情況,因爲該表那裏。我試圖將這兩個表映射到一個實體(表分割)上,但是因爲ParentId可以是NULL而EF爲此映射生成INNER JOIN而不是LEFT OUTER JOIN,所以它不起作用,因爲Measurement表中的某些行已被忽略,因爲它們沒有在Measurement_Parent中有任何相應的行。

基本上我需要的是具有可選的Parent屬性參考父測量和Children測量列表。

回答

2

你需要的是實體分割 - 在兩個或多個表中分割單個實體。這隱含地涉及共享主鍵 - 在這種情況下,關係表中的共享鍵將是子實體的ID。您可以通過調用多個Map方法來完成此操作,每個方法都調用EntityMappingConfiguration.Properties來定義哪些屬性應該包含在該映射片段中,並調用ToTable來設置表名稱。

modelBuilder.Entity<Measurement>() 
    .HasKey(ke => ke.MeasurementId) 
    .Map(emc => 
    { 
     emc.Properties(pe => new { pe.MeasurementId, pe.Name, pe.DeviceId }); 
     emc.ToTable("Measurement"); 
    }) 
    .Map(emc => 
    { 
     emc.Properties(pe => new { pe.MeasurementId, pe.ParentId }); 
     // maybe name this MeasurementExtension? This table could 
     // be used for any properties you wish to add to the Measurement entity 
     emc.ToTable("Measurement_Parent"); 

     // for this example's clarity I've named the PK Child_MeasurementId 
     // but in real-world use I would name it MeasurementId 
     emc.Property(pe => pe.MeasurementId).HasColumnName("Child_MeasurementId"); 
     emc.Property(pe => pe.ParentId).HasColumnName("Parent_MeasurementId"); 
    }); 

modelBuilder.Entity<Measurement>() 
    .HasOptional(npe => npe.Parent) 
    .WithMany(npe => npe.Children) 
    .HasForeignKey(fke => fke.ParentId); 

這裏的結果在DB(注意我並沒有建立一個FK/NAV道具爲Device,但你知道該怎麼做):

entity splitting result

理想情況下,Parent_MeasurementId場將爲not null,並且該記錄將被刪除,而不是將該列設置爲null(如果它們不是父項),但對於實體分割似乎不可能。無論如何,這正是你正在尋找的東西 - 擴展一個實體而不修改初始的基礎表。

+0

謝謝您的輸入。我嘗試過表分割的方法,但它有一個問題。因爲EF使用'INNER JOIN',所以'Measurement'沒有指定它的父指針,這意味着'Measurement_Parent'表中沒有相應的行,雖然對於我來說這個場景是有效的,因爲測量的父字段是可選的。 – RiZe

+0

您只需要爲每個「Measure」行創建一個'Measure_Parent'記錄,將'Parent' ID值設置爲null – Moho

相關問題