C# EF将第一个集合编码为ComplexType

C# EF将第一个集合编码为ComplexType,c#,entity-framework,ef-code-first,C#,Entity Framework,Ef Code First,出于性能原因,我正在将一组实体映射到一个视图,创建一个平面表(在某种程度上转换TPH中的TPT继承)。这仅用于特定的方法 [view] id property1 property2 propertyN complex_type_collection_property1 complex_type_collection_property2 complex_type_collection_propertyN 是否有一种方法可以将复杂类型集合属性映射到物化对象上的复杂属性 e、 g 谢谢大家! 好的,

出于性能原因,我正在将一组实体映射到一个视图,创建一个平面表(在某种程度上转换TPH中的TPT继承)。这仅用于特定的方法

[view]
id
property1
property2
propertyN
complex_type_collection_property1
complex_type_collection_property2
complex_type_collection_propertyN
是否有一种方法可以将复杂类型集合属性映射到物化对象上的复杂属性

e、 g

谢谢大家!

好的,我创建了,我假设您已经在我的代码中有了实体(
fromDB
变量,让我们假设它取自DB)或从DB检索到的实体。然后可以按如下所示强制转换每个实体。这个解决方案很全面,也不太复杂。您还应该指定与您的复杂类型对应的类型参数
Normalized
(如果您希望将复杂类型更改为另一个类型,则无需在转换方法上进行任何更改)。此外,复杂属性(City1、City2等)的名称必须包含集合属性(City)的名称,这是一些约定。我创建了具有共享属性的
BaseClass
,我们的两个类从中派生出来(因此您不能将字段从一个类复制到另一个类,而是应该将它们放入
BaseClass
)。此外,您只能有一个集合,即类型为
List
的属性

公共级城市
{
公共字符串名称{get;set;}
公共整数填充{get;set;}
}
公共类基类
{
公共int id{get;set;}
公共字符串名称{get;set;}
公共整数{get;set;}
}
公共类POCO:基类
{
公共城市1{get;set;}
公共城市2{get;set;}
公共城市3{get;set;}
}
公共类:基类
{
公共列表城市{get;set;}
公共静态显式运算符规范化(POCO self)
{
if(self==null)
返回null;
var normal=新的标准化();
foreach(typeof(BaseClass).GetProperties()中的var prop)
属性设置值(正常,属性获取值(自身));
var complexProp=typeof(Normalized).GetProperties().Where(x=>x.PropertyType.GetInterfaces().Any(y=>y.Name==“ICollection”).First();
complexProp.SetValue(普通,新列表((typeof(POCO).GetProperties()。其中(x=>x.Name.Contains(complexProp.Name))。选择(x=>(T)x.GetValue(self)).ToList());
恢复正常;
}
}
公共静态void Main(字符串[]args)
{
var fromDB=新POCO
{
年龄=20岁,
id=1,
Name=“Mike”,
城市1=新城{Name=“莫斯科”,人口=10},
City2=新城{Name=“伦敦”,人口=20},
City3=null
};
var normal=(标准化)fromDB;
Console.WriteLine(normal.City.Select(x=>x==null?“空”:x.Name).Aggregate((a,b)=>{returna+”,“+b;}));
}

谢谢您的回答!您将如何在这里发挥实体框架的作用?您会读取所有POCO,然后在运行时对其进行规范化吗?是的,我假设如下:
var normalList=context.MyTable.Where(x=>x.Age>5.ToList().Select(x=>(Normalized)x.ToList()我也简化了我的答案,看看吧。谢谢斯拉瓦。您的答案假设每行有多个城市,但是,命令context.MyTable.Where(x=>x.Age>5)将返回多个id相同的行,并且每个行都有一个城市。它甚至得到EF的支持吗?谢谢,我不明白你的意思。请求:context.MyTable.Where(x=>x.Age>5)将返回具有唯一ID的POCO列表(副本将如何显示?),此外,每个POCO内的所有城市(城市1、城市2)也将具有唯一ID(这取决于您如何指定POCO和城市表之间的关系)。MyTable是模型[视图]的表。您只需获取[view](POCO)列表,然后在类规范化的帮助下进行转换。在这种情况下,EF并不意味着任何您可以从任何地方获取[view]的内容:EF、文件、远程服务器、dataAdapter no metter。
[Object]
id = [view].Id
property1 = [view].property1
property2 = [view].property2
propertyN = [view].propertyN
Collection = [{property1 = [view].complex_type_collection_property1, ...}, ...]
public class City
{
    public string Name { get; set; }
    public int Population { get; set; }
}

public class BaseClass
{
    public int id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

public class POCO : BaseClass
{
    public City City1 { get; set; }
    public City City2 { get; set; }
    public City City3 { get; set; }
}

public class Normalized<T> : BaseClass
{
    public List<T> City { get; set; }

    public static explicit operator Normalized<T>(POCO self)
    {
        if (self == null)
            return null;

        var normal = new Normalized<T>();

        foreach (var prop in typeof(BaseClass).GetProperties())
            prop.SetValue(normal, prop.GetValue(self));

        var complexProp = typeof(Normalized<T>).GetProperties().Where(x => x.PropertyType.GetInterfaces().Any(y => y.Name == "ICollection")).First();
        complexProp.SetValue(normal, new List<T>((typeof(POCO).GetProperties().Where(x => x.Name.Contains(complexProp.Name)).Select(x => (T)x.GetValue(self)).ToList())));

        return normal;
    }
}

public static void Main(string[] args)
{
    var fromDB = new POCO
    {
        Age = 20,
        id = 1,
        Name = "Mike",
        City1 = new City { Name = "Moscow", Population = 10 },
        City2 = new City { Name = "London", Population = 20 },
        City3 = null
    };
    var normal = (Normalized<City>)fromDB;
    Console.WriteLine(normal.City.Select(x => x == null ? "EMPTY" : x.Name).Aggregate((a, b) => { return a + ", " + b; }));
}