Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Linq和连接到不同的属性_C#_Entity Framework_Linq_Reflection - Fatal编程技术网

C# Linq和连接到不同的属性

C# Linq和连接到不同的属性,c#,entity-framework,linq,reflection,C#,Entity Framework,Linq,Reflection,我有几个实体,我想加入linq。问题是我想加入的属性是动态的。例如: public class AClass { public int Id { get; set; } public string Name { get; set; } } public class BClass { public int Id { get; set; } public int AClassId{ get; set; } public virtual AClass A {

我有几个实体,我想加入linq。问题是我想加入的属性是动态的。例如:

public class AClass
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class BClass
{
    public int Id { get; set; }
    public int AClassId{ get; set; }
    public virtual AClass A { get; set; }

    public string String_Value_1 { get; set; }
    public string String_Value_2 { get; set; }
    public string String_Value_3 { get; set; }
}

public class Mapping
{
    public int Id { get; set; }
    public int AClassId{ get; set; }
    public virtual AClass A { get; set; }

    public string ColumnDesc{ get; set; }
    public string ColumnMappingName { get; set; }
}
例如,在我的AClass表中,将存储“n”个元素,每个元素可以具有存储字符串数据的源的不同映射

product_id=1
将具有映射
{ColumnDesc=“x”和ColumnMappingName=
“字符串\u值\u 1”}

//这意味着此产品的属性“x”的值存储在列字符串_value_1中

product_id=2
将具有映射
{ColumnDesc=“x”和ColumnMappingName=
“字符串\u值\u 2”}

//这意味着此产品的属性“x”的值存储在列String_value_2中

product_id=3
将具有映射
{ColumnDesc=“x”和ColumnMappingName=
“字符串\u值\u 3”}

//这意味着该产品的属性“x”的值存储在列String_value_3中

product\u id=4
将具有映射
{ColumnDesc=“x”和ColumnMappingName=“String\u Value\u 1”}

//这意味着此产品的属性“x”的值存储在列字符串_value_1中


我想做的是为定义了CoulmnDesc的AClass对象获取所有值(来自BClass)。我不想通过3个查询(字符串列可以是10个或更多)来实现,而是通过属性名或反射与使用lambda expresions动态地实现这一点。这应该是解决您问题的正确方法,不要担心大量的记录,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;
            }
        }
    }
问题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 a 4秒执行

查询2:7 a 8秒执行

启用外键和主键与不启用外键时的结果完全相同。我希望SQL server完全能够处理10.000.000的内存,数据库的大小只有2G

由于存储信息的“完美”方式,数据库可以在幕后使用各种优化(由于内部连接),非常轻松地进行查询。如果我只选择一个产品,结果非常快,计时器保持在0:00


[/EDIT3]

您是因为遗留系统而以这种方式构建数据,还是因为这是一个新项目?如果它是新的,我会完全不同的数据结构。它是新的项目。我明白你的意思,但如果有一百万个AClass对象,每个对象都有五个字符串属性,那么我的表中就有五百万个字符串。这不是我想要的。这将通过外键进行处理,它们将作为索引,因此只需要在内存中进行搜索,这是非常快的。无论如何,我会做一个新的。请稍等…添加了另一种方法来解决此问题。我想知道如何获取属性名“X”的值,该值可以存储在Value\u Column\u 1的一个AClass对象中,在Value\u Column\u 2的下一个AClass对象中,另一个Value\u Column\u 3和在另一个AClass对象中不存在,但将是其他的。我不想有3个问题。我的目标类似于EAV模式,但我已经了解到,在MS SQL中很难实现它,很难进行搜索、排序等,并且在Linq和EF中处理它,下一个想法是通过xml列进行处理,但EF不支持它:(.下一个想法是使用“n-amount”字符串列“y-amount”带boolYou的int列等有1个查询:从属性值pv内部联接AClass a中选择*在a上。Id=pv.AClassId内部联接属性名称n在n上。Id=pv.PropertyNameId
SELECT TOP 1000000 *
  FROM [test].[dbo].[products]
  ORDER BY NEWID()
SELECT TOP 1000000 *
  FROM [test].[dbo].[products] p
  INNER JOIN [test].[dbo].[View_1] v
  ON v.ProductId = p.Id
  ORDER BY NEWID()