C# 如何从实体框架元数据EntityType对象获取相应的POCO对象类型?

C# 如何从实体框架元数据EntityType对象获取相应的POCO对象类型?,c#,entity-framework,ef-code-first,C#,Entity Framework,Ef Code First,我已经用一些额外的元数据(例如,或者可能是新的自定义属性)注释了Entity Framework Code First对象。一旦我有了EF代码第一个POCO对象的类型对象,这个代码的一个版本(from)就可以很好地读取属性 但是,我不知道如何从MetadataWorkspace中找到所有实体: ObjectContext objContext = ((IObjectContextAdapter)this).ObjectContext; MetadataWorkspace mw = objCont

我已经用一些额外的元数据(例如,或者可能是新的自定义属性)注释了Entity Framework Code First对象。一旦我有了EF代码第一个POCO对象的类型对象,这个代码的一个版本(from)就可以很好地读取属性

但是,我不知道如何从MetadataWorkspace中找到所有实体:

ObjectContext objContext = ((IObjectContextAdapter)this).ObjectContext;
MetadataWorkspace mw = objContext.MetadataWorkspace;
var entities = mw.GetItems<EntityType>(DataSpace.OSpace);
ObjectContext objContext=((IOObjectContextAdapter)this).ObjectContext;
MetadataWorkspace mw=objContext.MetadataWorkspace;
var entities=mw.GetItems(DataSpace.OSpace);
对于POCO类类型,我需要考虑属性

如何从
EntityType
获取POCO对象或其代理?或者,如果没有GetItems(),如何在上下文中找到所有POCO对象?

相关链接:


可能有一种直接的方法,但您可以从全名中获取类型

var types=来自实体中的实体
选择Type.GetType(entity.FullName);

如果我没有弄错您想要的-这应该会有帮助,因为它描述了一个类似的问题我刚才发布的:

另请查看这篇文章,它总结了这一切:


(都是我以前的职位)

简言之,我设法阅读了大部分信息——但事实并非如此 完美(如果我没记错的话,我现在不能检查)并且有一些 特定情况下的问题,取决于您确切需要什么)


如果它对其他人有帮助,这是我的测试工具代码,用于从我的EF设置(特别是一个CSV数据库)中转储我的DbContext POCO代理:

MyContext ctx=newmycontext();
变量元数据=((IObjectContextAdapter)ctx).ObjectContext.MetadataWorkspace;
var schema=metadata.GetItems(DataSpace.SSpace.ToList();
字典表=新字典();
字典类型=新字典();
字典表_name=新字典();
foreach(架构中的var项)
{
if(item.ToString()包含(“CodeFirstDatabaseSchema”)&&!item.ToString()包含(“\u”))
{
字符串[]tableItem=item.ToString().Split('.');
字符串名称=tableItem[1];
Debug.WriteLine(“表名称:”+name);
如果(!tables.ContainsKey(名称))
{
System.Data.Entity.Core.Metadata.Edm.EntityType Entity\u type=项为System.Data.Entity.Core.Metadata.Edm.EntityType;
if(实体类型!=null)
{
列表列=新列表();
var成员=实体\类型。申报成员;
foreach(成员中的var成员)
{
columns.Add(member.ToString());
}
Debug.WriteLine(“columns:\n”+string.Join(“,”,columns));
表。添加(名称、列);
类型。添加(名称、实体类型);
table_names.Add(name,item.MetadataProperties[“TableName”].Value.ToString());
}
}
}
}
foreach(表.Keys中的变量表名称)
{
列表列=表格[表格名称];
System.Data.Entity.Core.Metadata.Edm.EntityType实体=类型[表名称];
字符串table_csv_name=table_name[table_name]+“.csv”;
Debug.WriteLine(“table\u csv\u name:+table\u csv\u name”);
var assembly_name=AssemblyName.GetAssemblyName(“MyDLL.dll”);
var proxy=metadata.GetItems(DataSpace.OSpace).Where(v=>v.Name==table_Name).FirstOrDefault();
Type proxy\u Type=Type.GetType(proxy.FullName+,“+assembly\u name.FullName);
if(代理类型!=null)
{
var set=ctx.set(代理类型);
foreach(集合中的变量行)
{
Debug.WriteLine(“行:”+行);
}
}
}

然后,我得到了通过POCO属性上的反射将DbSet对象转储回csv的代码。注意上面的
CodeFirstDatabaseSchema
literal是我认为的,YMMV

在运行时无法向现有类型定义添加自定义属性。为了修饰您的实体,您必须在定义实体的源文件中这样做(或者通过创建关联类型来保存元数据/属性注释,以防直接编辑源文件不是一个选项;但是对于EF代码,首先您不应该有这个问题)。抱歉,我不清楚。我并没有试图添加属性,我只是试图通过反射来阅读它们。我希望是为了澄清而编辑的。代理类应该继承自您的POCO类。我想你可以看看
proxyType.BaseType
@cadrell0:我也没有代理类型-我怎么要求这些?这不是万无一失的。FullName属性并不总是与程序集类型名称相对应。不适合我。
        MyContext ctx = new MyContext();
        var metadata = ((IObjectContextAdapter)ctx).ObjectContext.MetadataWorkspace;
        var schema = metadata.GetItems(DataSpace.SSpace).ToList();
        Dictionary<string, List<string>> tables = new Dictionary<string, List<string>>();
        Dictionary<string, System.Data.Entity.Core.Metadata.Edm.EntityType> types = new Dictionary<string, System.Data.Entity.Core.Metadata.Edm.EntityType>();
        Dictionary<string, string> table_names = new Dictionary<string, string>();
        foreach (var item in schema)
        {
            if (item.ToString().Contains("CodeFirstDatabaseSchema") && !item.ToString().Contains("_"))
            {
                string[] tableItem = item.ToString().Split('.');
                string name = tableItem[1];
                Debug.WriteLine("table_name: " + name);

                if (!tables.ContainsKey(name))
                {
                    System.Data.Entity.Core.Metadata.Edm.EntityType entity_type = item as System.Data.Entity.Core.Metadata.Edm.EntityType;
                    if (entity_type != null)
                    {
                        List<string> columns = new List<string>();
                        var members = entity_type.DeclaredMembers;
                        foreach (var member in members)
                        {
                            columns.Add(member.ToString());
                        }
                        Debug.WriteLine("columns:\n" + string.Join(",", columns));
                        tables.Add(name, columns);
                        types.Add(name, entity_type);
                        table_names.Add(name, item.MetadataProperties["TableName"].Value.ToString());
                    }
                }
            }
        }
        foreach (var table_name in tables.Keys)
        {
            List<string> columns = tables[table_name];
            System.Data.Entity.Core.Metadata.Edm.EntityType entity = types[table_name];
            string table_csv_name = table_names[table_name] + ".csv";
            Debug.WriteLine("table_csv_name: " + table_csv_name);
            var assembly_name = AssemblyName.GetAssemblyName("MyDLL.dll");
            var proxy = metadata.GetItems<System.Data.Entity.Core.Metadata.Edm.EntityType>(DataSpace.OSpace).Where(v => v.Name == table_name).FirstOrDefault();
            Type proxy_type = Type.GetType(proxy.FullName + ", " + assembly_name.FullName);
            if (proxy_type != null)
            {
                var set = ctx.Set(proxy_type);
                foreach (var row in set)
                {
                    Debug.WriteLine("row: " + row);
                }
            }
        }