我正在嘗試使用實體框架代碼優先實現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)來輕鬆實現我所描述的功能。 –