2

我正在嘗試使用實體框架代碼優先實現Web應用程序。 我會解釋這個例子的問題:如何創建「動態」數據庫結構(EF代碼優先)

在我的數據庫中有一個產品集合。

public class Product 
{ 
    public long Id { get; set; } 
    public string Name { get; set; } 
    public virtual Type type { get; set; } 
    //..... Some other properties ..... 
} 

每個產品都有它自己的類型(食品,藥品,多媒體等)。在我的數據庫中,也是這種類型的集合,它將由最終用戶定義,並可能在將來進行修改/增加。

public class Type 
{ 
    public long Id { get; set; } 
    public string Name { get; set; } 
    //..... Some other properties ..... 
} 

如您所知,每種產品都有自己的屬性取決於產品的類型。比方說藥物可能具有

public bool PrescriptionOnly { get; set; } 

和多媒體類型可以具有

public Size DisplaySize { get; set; } 

正如我所提到之前types'll由最終用戶來定義,以便計數特性和每個屬性的數據類型是未定義的馬上。此外,用戶應該能夠通過特定的屬性值來過濾產品(過濾模型取決於產品類型)。這一切都應該使用Code-First模型來實現。

總結起來,我卡住了,因爲我不知道如何用EF Code-First創建這樣的「動態」數據庫結構。我想要在Type類中創建一個字符串字段並保存[key = value]對,但這幾乎不可能創建快速高效的分頁結果填充。

我會很樂意爲我的問題提出任何建議或解決方案。

此致敬禮! 盧卡斯


我創造了這樣的示例代碼,以可視化的問題。數據庫結構如下所示:

組別= 「民以食爲天」[Property1 = 「ForVegetarian」,Property2 = 「卡路里」] ## - 產品1 = 「比薩」[ 「假」, 「1500」] - 產品1 = 「色拉」[ 「真」, 「300」]

類別2 = 「多媒體」[Property1 = 「顯示尺寸」,Property2 = 「保證」] ## - 產品1 = 「PlasmaTV」[「55' 「」, 「36米」] - 產品1 = 「LCD監視器」[ 「24 ''」, 「12M」]

public class Property 
{ 
    public long Id { get; set; } 
    public string Name { get; set; } 
} 

public class ProductCategory 
{ 
    public long Id { get; set; } 
    public string Name { get; set; } 
    public virtual ICollection<Property> Properties { get; set; } 
    public virtual ICollection<Product> Products { get; set; } 
} 

public class PropertyValue 
{ 
    public long Id { get; set; } 
    public virtual Property Property { get; set; } 
    public string Value { get; set; } 
} 

public class Product 
{ 
    public long Id { get; set; } 
    public string Name { get; set; } 
    public virtual ICollection<ProductCategory> Categories { get; set; } 
    public virtual ICollection<PropertyValue> Properties { get; set; } 
} 

public class TestDataBase : DbContext 
{ 
    public DbSet<ProductCategory> Categories { get; set; } 
    public DbSet<Property> Properties { get; set; } 
    public DbSet<PropertyValue> Values { get; set; } 
    public DbSet<Product> Products { get; set; } 
    public TestDataBase() 
    { } 
    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { } 
    public static readonly TestDataBase context = new TestDataBase(); 
} 

public class TestDataBaseInitializer : DropCreateDatabaseIfModelChanges<TestDataBase> 
{ 
    protected override void Seed(TestDataBase context) 
    { 
     ProductCategory cat1 = new ProductCategory 
           { 
            Name = "Food", 
            Properties = new List<Property>(), 
            Products = new List<Product>() 
           }; 
     Property prop1_1 = new Property 
          { 
           Name = "ForVegetarian" 
          }; 
     Property prop1_2 = new Property 
          { 
           Name = "Calories" 
          }; 
     cat1.Properties.Add(prop1_1); 
     cat1.Properties.Add(prop1_2); 
     Product product1_1 = new Product 
          { 
           Name = "Pizza", 
           Categories = new List<ProductCategory>(), 
           Properties = new List<PropertyValue>() 
          }; 
     product1_1.Categories.Add(cat1); 
     PropertyValue val1_1_1 = new PropertyValue 
           { 
            Property = prop1_1, 
            Value = "false" 
           }; 
     PropertyValue val1_1_2 = new PropertyValue 
           { 
            Property = prop1_2, 
            Value = "1500" 
           }; 
     product1_1.Properties.Add(val1_1_1); 
     product1_1.Properties.Add(val1_1_2); 
     cat1.Products.Add(product1_1); 
     Product product1_2 = new Product 
     { 
      Name = "Salad", 
      Categories = new List<ProductCategory>(), 
      Properties = new List<PropertyValue>() 
     }; 
     product1_2.Categories.Add(cat1); 
     PropertyValue val1_2_1 = new PropertyValue 
     { 
      Property = prop1_1, 
      Value = "true" 
     }; 
     PropertyValue val1_2_2 = new PropertyValue 
     { 
      Property = prop1_2, 
      Value = "300" 
     }; 
     product1_2.Properties.Add(val1_2_1); 
     product1_2.Properties.Add(val1_2_2); 
     cat1.Products.Add(product1_2); 
     //-------------------------------------------------------------------------------- 
     ProductCategory cat2 = new ProductCategory 
           { 
            Name = "Multimedia", 
            Properties = new List<Property>(), 
            Products = new List<Product>() 
           }; 
     Property prop2_1 = new Property 
          { 
           Name = "DisplaySize" 
          }; 
     Property prop2_2 = new Property 
          { 
           Name = "Warranty" 
          }; 
     cat2.Properties.Add(prop2_1); 
     cat2.Properties.Add(prop2_2); 
     Product product2_1 = new Product 
          { 
           Name = "PlasmaTV", 
           Categories = new List<ProductCategory>(), 
           Properties = new List<PropertyValue>() 
          }; 
     product2_1.Categories.Add(cat2); 
     PropertyValue val2_1_1 = new PropertyValue 
           { 
            Property = prop2_1, 
            Value = "55''" 
           }; 
     PropertyValue val2_1_2 = new PropertyValue 
           { 
            Property = prop2_2, 
            Value = "36m" 
           }; 
     product2_1.Properties.Add(val2_1_1); 
     product2_1.Properties.Add(val2_1_2); 
     cat2.Products.Add(product2_1); 
     Product product2_2 = new Product 
     { 
      Name = "LCDMonitor", 
      Categories = new List<ProductCategory>(), 
      Properties = new List<PropertyValue>() 
     }; 
     product2_2.Categories.Add(cat2); 
     PropertyValue val2_2_1 = new PropertyValue 
     { 
      Property = prop2_1, 
      Value = "24''" 
     }; 
     PropertyValue val2_2_2 = new PropertyValue 
     { 
      Property = prop2_2, 
      Value = "12m" 
     }; 
     product2_2.Properties.Add(val2_2_1); 
     product2_2.Properties.Add(val2_2_2); 
     cat2.Products.Add(product2_2); 
     context.Properties.Add(prop1_1); 
     context.Properties.Add(prop1_2); 
     context.Properties.Add(prop2_1); 
     context.Properties.Add(prop2_2); 
     context.Values.Add(val1_1_1); 
     context.Values.Add(val1_1_2); 
     context.Values.Add(val1_2_1); 
     context.Values.Add(val1_2_2); 
     context.Values.Add(val2_1_1); 
     context.Values.Add(val2_1_2); 
     context.Values.Add(val2_2_1); 
     context.Values.Add(val2_2_2); 
     context.Categories.Add(cat1); 
     context.Categories.Add(cat2); 
     context.SaveChanges(); 
    } 
} 

現在讓我們說我在裏面多媒體類別:

 var category = (from c in TestDataBase.context.Categories 
         where c.Name == "Multimedia" 
         select c).First(); 

我知道,這一類具有兩個屬性:顯示尺寸保修 可以說,我想選擇所有產品(如IEnumerable)其中多媒體類別(請注意,產品可能在多個類別中)。

 var categoryProducts = (from c in TestDataBase.context.Categories 
           where c.Name == "Multimedia" 
           select c.Products).First(); 

此外,我必須得到顯示尺寸屬性篩選項目組的產品。我想選擇哪個這些產品:

  • 具有NOT NULL 顯示尺寸財產
  • 顯示尺寸 == 55 ''

而且這裏去了一個問題:我不知道如何在中指定LINQ to Entity來選擇這樣的產品,因爲每個產品都有自己的PropertyValue對象集合 - 而不僅僅是一個PropertyValue。

任何人都可以給我一個幫助。先謝謝你!

+0

我不明白你的問題?你的意思是像ORM或對象序列化? – shox

+0

不,我的意思是數據庫設計(ADO.NET,EF,Code-First)來輕鬆實現我所描述的功能。 –

回答