我想通过linq加入一些实体。问题是我想加入的财产是动态的。例如:
product_id = 1
例如在我的AClass表中将存储" n" - 元素,每个元素可以有不同的源映射,其中存储了字符串数据。
{ColumnDesc = "x" and ColumnMappingName =
"String_Value_1"}
将有映射product_id = 2
//这意味着财产的价值" x"在String_Value_1
列中存储此产品 {ColumnDesc = "x" and ColumnMappingName =
"String_Value_2"}
将有映射product_id = 3
//这意味着财产的价值" x"在String_Value_2
列中存储此产品 {ColumnDesc = "x" and ColumnMappingName =
"String_Value_3"}
将有映射product_id = 4
//这意味着财产的价值" x"在String_Value_3
列中存储此产品 {ColumnDesc = "x" and ColumnMappingName = "String_Value_1"}
将有映射{{1}}
//这意味着财产的价值" x"在String_Value_1
列中存储此产品我想要做的是获取已定义CoulmnDesc的AClass对象的所有值(来自BClass)。我不想通过3个查询(字符串列可以是10或甚至更多)来执行它,而是通过使用lambda expresions通过属性名称或反射来动态地执行它
答案 0 :(得分:0)
这应该是您问题的正确解决方案,不要担心大量记录,SQL Server会找到一种方法来快速获取数据。
public class AClass
{
public int Id { get; set; }
public string Name { get; set; }
[ForeignKey("AClassId")]
public virtual List<PropertyValue> PropertyValues { get; set; }
}
// Id = 1, Name = "P1"
// Id = 2, Name = "P2"
// Id = 3, Name = "P3"
public class PropertyValue
{
public int Id { get; set; }
public int AClassId { get; set; }
[ForeignKey("AClassId")]
public virtual AClass A { get; set; }
public int PropertyNameId { get; set; }
[ForeignKey("PropertyNameId")]
public virtual PropertyName PropertyName { get; set; }
public string Value { get; set; }
}
// Id = 1, AClassId = 1, PropertyNameId = 1, Value = "p1 x1 y1"
// Id = 2, AClassId = 1, PropertyNameId = 2, Value = "p1 x2 y2"
// Id = 3, AClassId = 1, PropertyNameId = 3, Value = "p1 x3 y3"
// Id = 4, AClassId = 2, PropertyNameId = 2, Value = "p2 x2 y2"
// Id = 5, AClassId = 2, PropertyNameId = 3, Value = "p2 x3 y3"
// Id = 6, AClassId = 2, PropertyNameId = 4, Value = "p2 x4 y4"
// Id = 7, AClassId = 3, PropertyNameId = 3, Value = "p3 x3 y3"
// Id = 8, AClassId = 3, PropertyNameId = 4, Value = "p3 x4 y4"
// Id = 9, AClassId = 3, PropertyNameId = 5, Value = "p3 x5 y5"
public class PropertyName
{
public int Id { get; set; }
public string Name { get; set; }
[ForeignKey("PropertyId")]
public virtual List<PropertyValue> PropertyValues { get; set; }
}
// Id = 1, PropertyName = "x1"
// Id = 2, PropertyName = "x2"
// Id = 3, PropertyName = "x3"
// Id = 4, PropertyName = "x4"
// Id = 5, PropertyName = "x5"
public void DoStuff()
{
List<AClass> productlist = new List<AClass>();
foreach (var product in productlist)
{
var productname = product.Name;
foreach (var property in product.PropertyValues)
{
var propertyname = property.PropertyName.Name;
var propertyvalue = property.Value;
}
}
}
[编辑]
您的原始解决方案是可行的,我将向您展示&#34;学习目的&#34;。
public class AClass
{
public int Id { get; set; }
public string Name { get; set; }
[ForeignKey("AClassId")]
public virtual List<PropertySet> PropertySets { get; set; }
}
public class PropertySet
{
public int Id { get; set; }
public int AClassId { get; set; }
[ForeignKey("AClassId")]
public virtual AClass A { get; set; }
public int PropertyNameId_Column1 { get; set; }
[ForeignKey("PropertyNameId_Column1")]
public virtual PropertyName PropertyName_Column1 { get; set; }
public string Value_Column1 { get; set; }
public int PropertyNameId_Column2 { get; set; }
[ForeignKey("PropertyNameId_Column2")]
public virtual PropertyName PropertyName_Column2 { get; set; }
public string Value_Column2 { get; set; }
public int PropertyNameId_Column3 { get; set; }
[ForeignKey("PropertyNameId_Column3")]
public virtual PropertyName PropertyName_Column3 { get; set; }
public string Value_Column3 { get; set; }
}
public class PropertyName
{
public int Id { get; set; }
public string Name { get; set; }
[ForeignKey("PropertyNameId_Column1")]
public virtual List<PropertySet> PropertySets_Column1 { get; set; }
[ForeignKey("PropertyNameId_Column2")]
public virtual List<PropertySet> PropertySets_Column2 { get; set; }
[ForeignKey("PropertyNameId_Column3")]
public virtual List<PropertySet> PropertySets_Column3 { get; set; }
}
我添加了此解决方案,因此您可以了解如何在EF中进行多重映射。 (想想:AddedByUser,UpdatedByUser等。)请不要使用这种方法来解决你的问题,这将是一个不好的做法和很多工作。
[/编辑]
[EDIT2]
在我以前工作的公司里,我有这个同事说完全一样的东西(&#34;这个系统不适用于数百万条记录&#34;)。他制定了一些比特方式的比较方法来映射他预定义的属性。这个系统确实使用了1.000.000+记录,但我从来没有花时间正确地反驳他的方法。
你现在将成为我的受害者;)哈哈
我目前正在使用5.000.000产品创建测试环境。每个产品都分配了3个值,创建了一个15.000.000记录的值表。
[/ EDIT2]
[EDIT3]
好的,这是出乎意料的,我做了2次测试:
查询1.选择随机1.000.000产品
SELECT TOP 1000000 *
FROM [test].[dbo].[products]
ORDER BY NEWID()
查询2.选择随机1.000.000产品,内部连接属性
SELECT TOP 1000000 *
FROM [test].[dbo].[products] p
INNER JOIN [test].[dbo].[View_1] v
ON v.ProductId = p.Id
ORDER BY NEWID()
猜测结果:
查询1:3执行4秒
查询2:7执行8秒
启用外键和主键时的结果完全相同。我希望SQL服务器完全能够在内存中处理10.000.000,数据库只有2 gig的大小。
因为&#34;完美&#34;存储信息的方式数据库可以使用引擎盖下的各种优化(因为INNER JOINS)非常容易查询。如果我只选择1个产品,结果会很快,计时器会保持在0:00。
[/ EDIT3]