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)来轻松实现我所描述的功能。 –

回答