我正在尝试使用实体框架代码优先实现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。
任何人都可以给我一个帮助。先谢谢你!
我不明白你的问题?你的意思是像ORM或对象序列化? – shox
不,我的意思是数据库设计(ADO.NET,EF,Code-First)来轻松实现我所描述的功能。 –