我正在尝试使用Entity Framework Code-First实现Web应用程序。 我将在这样的例子中解释这个问题:
在我的数据库中有一系列产品。
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; }
正如我之前提到的,类型将由最终用户定义,因此每个属性的属性和数据类型的计数现在都是未定义的。此外,用户应该能够通过特定的属性值过滤产品(过滤模型取决于产品类型)。这一切都应该使用Code-First模型来实现。
总而言之,我已经陷入困境,因为我不知道如何使用EF Code-First创建这样的“动态”数据库结构。我想在Type类中创建一个字符串字段并保存[key = value]对,但这几乎不可能用分页结果创建快速有效的填充。
对于我的问题的任何建议或解决方案,我将感激不尽。
祝你好运! 卢卡斯
我已经创建了这样的示例代码来可视化问题。数据库结构如下所示:
Category1 =“食物”[Property1 =“ForVegetarian”,Property2 =“Calories”] ## - Product1 =“Pizza”[“false”,“1500”] - Product1 =“Salad”[“true”,“300”]
Category2 =“Multimedia”[Property1 =“DisplaySize”,Property2 =“Warranty”] ## - Product1 =“PlasmaTV”[“55”',“36m”] - Product1 =“LCDMonitor”[“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();
我知道此类别有两个属性: DisplaySize 和保修 假设我想选择多媒体类别中的所有产品( IEnumerable )(请注意,产品可能位于多个类别中)。
var categoryProducts = (from c in TestDataBase.context.Categories
where c.Name == "Multimedia"
select c.Products).First();
此外,我必须通过 DisplaySize 属性过滤这组产品。我想选择那些产品:
这就出现了问题:我不知道如何在 LINQ to Entity 中指定选择此类产品,因为每个产品都有自己的PropertyValue对象集合 - 而不仅仅是一个PropertyValue
有人能给我一个帮助。提前谢谢!
答案 0 :(得分:0)
行。我想我已经解决了我的问题。
var categoryProducts = (from p in category.Products
from c in p.Properties
where c.Property.Name == "DisplaySize" &&
c.Value == "55''"
select p).ToList();
这是关于此类选择的好文章: http://weblogs.asp.net/salimfayad/archive/2008/07/09/linq-to-entities-join-queries.aspx