【问题标题】:How do I get the corresponding POCO object Type from an Entity Framework Metadata EntityType object?如何从实体框架元数据 EntityType 对象中获取相应的 POCO 对象类型?
【发布时间】:2017-09-05 14:25:58
【问题描述】:

我用一些额外的元数据注释了我的 Entity Framework Code First 对象,例如 DataTypeAttribute 或可能是新的自定义属性。一旦我拥有 EF Code First POCO 对象的 Type 对象,此代码的一个版本(来自 http://www.minddriven.de/index.php/technology/dot-net/web/asp-net-mvc/check-data-annotations-from-code)可以很好地读取属性。

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

ObjectContext objContext = ((IObjectContextAdapter)this).ObjectContext;
MetadataWorkspace mw = objContext.MetadataWorkspace;
var entities = mw.GetItems<EntityType>(DataSpace.OSpace);

到我需要反映在属性上的 POCO 类类型。

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

相关链接:

【问题讨论】:

  • 无法在运行时向现有类型定义添加自定义属性 (ttbomk)。为了装饰您的实体,您必须在定义它们的源文件中这样做(或通过创建关联类型来仅保存元数据/属性注释,以防直接编辑源文件不是一种选择;对于 EF 代码-首先你不应该有这个问题)。
  • 对不起,我不清楚。我不是想添加属性,我只是想通过反射来阅读它们。编辑澄清,我希望。
  • 代理类应该继承自你的 POCO 类。我想你可以看看proxyType.BaseType
  • @cadrell0:我也没有代理类型 - 我如何要求这些?

标签: c# entity-framework ef-code-first


【解决方案1】:

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

var types = from entity in entities
            select Type.GetType(entity.FullName);

【讨论】:

  • 这不是万无一失的。 FullName 属性并不总是对应于程序集类型名称。对我不起作用。
【解决方案2】:

如果我是正确的你想要的 - 这应该会有所帮助,因为它描述了一个类似的问题我不久前发布的:

How check by unit test that properties mark as computed in ORM model?

还可以查看其他帖子,其中总结了这一切:

Get Model schema to programmatically create database using a provider that doesn't support CreateDatabase
(都是我之前的帖子)

简而言之,我设法阅读了大部分信息 - 但事实并非如此 完美(如果我没记错的话,我现在无法检查)并且有一些 某些情况下的问题,取决于您的确切需求)。

【讨论】:

    【解决方案3】:

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

            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);
                    }
                }
            }
    

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

    【讨论】:

      猜你喜欢
      • 2011-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-29
      • 2020-10-24
      • 1970-01-01
      相关资源
      最近更新 更多