【问题标题】:Searching EDMX metadata using C# and LINQ Yields no results使用 C# 和 LINQ 搜索 EDMX 元数据没有结果
【发布时间】:2020-10-12 17:20:04
【问题描述】:

我正在尝试解析并通过此元数据搜索我正在使用 C# 处理的项目。 最终结果是加载 xml 文件(如下),找到名称为“docChemicalReport”的 EntityType,然后遍历表结构。轻松的目标。我遇到的问题是我无法让它返回任何东西。

元数据在这里:https://apps.fielddirect.com/DataServices/OData/$metadata 示例代码:

<edmx:Edmx Version="1.0">
<edmx:DataServices m:DataServiceVersion="3.0" m:MaxDataServiceVersion="3.0">
<Schema Namespace="IHSFD.Database.Context">
<EntityType Name="CorpPurchaser">
<Key>
<PropertyRef Name="CorpPurchaserID"/>
</Key>
<Property Name="CorpPurchaserID" Type="Edm.Int32" Nullable="false"/>
<Property Name="CorpID" Type="Edm.Int32" Nullable="false"/>
<Property Name="CorpPurchaserName" Type="Edm.String" Nullable="false"/>
<Property Name="Email" Type="Edm.String"/>
<Property Name="PhoneNumber" Type="Edm.String"/>
<Property Name="PhoneExt" Type="Edm.String"/>
<Property Name="CreatedDate" Type="Edm.DateTime" Nullable="false"/>
<Property Name="CreatedBy" Type="Edm.String"/>
<Property Name="ModifiedDate" Type="Edm.DateTime" Nullable="false"/>
<Property Name="ModifiedBy" Type="Edm.String"/>
</EntityType>
<EntityType Name="docChemicalReport">
<Key>
<PropertyRef Name="DocIDChemicalReports"/>
</Key>
<Property Name="DocIDChemicalReports" Type="Edm.Int32" Nullable="false"/>
<Property Name="UserID" Type="Edm.String"/>
<Property Name="EntityID" Type="Edm.Int32" Nullable="false"/>
<Property Name="EntityTypeID" Type="Edm.Int16" Nullable="false"/>
<Property Name="docDate" Type="Edm.DateTime" Nullable="false"/>
<Property Name="ChemCoCode" Type="Edm.Int16"/>
<Property Name="ChemicalName" Type="Edm.String"/>
<Property Name="ChemTypeCode" Type="Edm.Int16"/>
<Property Name="InjectPointTypeID" Type="Edm.Int16"/>
<Property Name="BeginInven" Type="Edm.Single"/>
<Property Name="EndInven" Type="Edm.Single"/>
<Property Name="UnitsDelivered" Type="Edm.Single"/>
<Property Name="UnitsDelivCode" Type="Edm.Int16"/>
<Property Name="UnitsApplied" Type="Edm.Single"/>
<Property Name="UnitsAppliedCode" Type="Edm.Int16"/>
<Property Name="ApplicationCost" Type="Edm.Decimal"/>
<Property Name="AppMethodCode" Type="Edm.Int16"/>
<Property Name="UnitsFlush" Type="Edm.Single"/>
<Property Name="UnitsFlushCode" Type="Edm.Int16"/>
<Property Name="FlushTypeCode" Type="Edm.Int16"/>
<Property Name="Stamp" Type="Edm.DateTime" Nullable="false"/>
<Property Name="Notes" Type="Edm.String"/>
<Property Name="InputByID" Type="Edm.String"/>
<Property Name="DocSourceCode" Type="Edm.Int16"/>
</EntityType>

我使用的示例来自 MS:https://docs.microsoft.com/en-us/dotnet/standard/linq/find-element-specific-attribute

所以,我从根目录中获取了名称空间,并进行了快速查询,但它没有产生任何结果。

    TextReader tr = new StringReader(responseFromServer);
    XDocument xmlDoc2 = XDocument.Load(tr);
   
    XElement root = xmlDoc2.Root;

    XElement entityType = root;
    XNamespace ns = entityType.GetDefaultNamespace();

    IEnumerable<XElement> et =
        from el in root.Elements(ns + "EntityType")
        where (string)el.Attribute(ns + "Name") == "docChemicalReport"
        select el;
    foreach (XElement el in et)
        Console.WriteLine(el);

我的问题是,我是否过于复杂了?我应该使用不同的 xml 技术来搜索和读取属性吗?我的代码的哪一部分不正确...

【问题讨论】:

  • 您有示例 xml 吗?您通常没有属性名称空间,并且标签名称可能不在根目录下。所以试试: from el in root.Descendants(ns + "EntityType") where (string)el.Attribute("Name") == "docChemicalReport"
  • @jdweng,我在帖子顶部发布了一个 xml 示例,以及一个指向实际 xml 的链接。将其更改为 root.Descendants 并没有帮助。仍然没有返回任何东西。
  • 任何人都可以一起玩,我将它加载到 dotnetfiddle 中。 dotnetfiddle.net/15t2jV
  • 你可以通过阅读EF的元数据来做到这一点:stackoverflow.com/q/6056597/861716
  • @GertArnold,这看起来有点超出我的技能水平。感谢您的评论,但我不明白我将如何使用它。我认为只需一个简单的 linq 查询就可以帮助我到达我需要去的地方。

标签: c# xml linq edmx


【解决方案1】:

看看以下是否有帮助:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            XElement schema = doc.Descendants().Where(x => x.Name.LocalName == "Schema").FirstOrDefault();
            int v = 0;
            string z = v.GetType().ToString(); 
            XNamespace ns = schema.GetDefaultNamespace();
            Dictionary<string, Entity> entityTypes = schema.Descendants(ns + "EntityType")
                .Select(x => new Entity() {
                    name = (string)x.Attribute("Name"),
                    key = (string)x.Descendants(ns + "PropertyRef").FirstOrDefault().Attribute("Name"),
                    properties = x.Elements(ns + "Property").Select(y => new Property()
                    {
                        name = (string)y.Attribute("Name"),
                        _type = Type.GetType("System." + ((string)y.Attribute("Type")).Split(new char[] {'.'}).Last()),
                        nullable = (y.Attribute("Nullable") == null)? (Boolean?)null : ((string)y.Attribute("Nullable") == "false")? false : true
                    }).ToList()
                }).GroupBy(x => x.key, y => y)
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());
        }

    }
    public class Entity
    {
        public string name { get; set; }
        public string key { get; set; }
        public List<Property> properties { get; set; }
    }
    public class Property
    {
        public string name { get; set; }
        public Type _type { get; set; }
        public Boolean? nullable { get; set; }
    }

}

【讨论】:

  • 是的,所以我需要的部分是如何只选择一个显示“docChemicalReport”的部分,然后循环遍历它的属性?那是我缺少的部分(顺便说一句,感谢您的耐心等待)。因此,选择具有 EntityType name='docChemicalReport' 的节点,然后遍历属性元素并将其中的属性读取到列表中。
  • 感谢您的更新。让代码工作,我看到它全部加载到一个包含所有信息的字典中,现在我只需要循环浏览字典,然后选择我假设的项目属性。我会搞砸这个,但这比我自己能得到的还远。
  • 嘿@jdweng,所以,愚蠢的问题......我运行了代码,它工作了,但它遗漏了文件中的最后两个条目......没有抱怨,因为我能够完成我的解决方案,只需手动处理其余部分.. 但是当我查看创建的实体时,它们根本不在字典中。我很好奇为什么会发生这种情况,以备将来使用。
  • 字典可能不按顺序或架构问题。缺少哪些项目?有一条警告消息:警告 3 命名空间“schemas.microsoft.com/ado/2007/06/edmx”中的元素“DataServices”在命名空间“schemas.microsoft.com/ado/2009/11/edm”中具有无效的子元素“Schema”。预期的可能元素列表:命名空间“schemas.microsoft.com/ado/2006/04/edm”中的“架构”。 C:\Users\Joel\AppData\Local\Temporary Projects\ConsoleApplication1\XMLFile1.xml 4 6 ConsoleApplication1
猜你喜欢
  • 2019-11-28
  • 1970-01-01
  • 2010-10-28
  • 2017-04-02
  • 2018-01-15
  • 2018-03-11
  • 2016-04-30
  • 2014-01-15
相关资源
最近更新 更多