如何使用Linq to SQL和Linq to XML查询数据库列中的XML数据?

问题描述

| XML:
<root>
    <item>
        <href>http://myurl</href>
    </item>
    <item>
        <href>http://myurl2</href>
    </item>
</root>
XML数据存储在数据库表中。 我可以建立一个Linq查询来选择行,提取XML,然后例如提取所有href标签吗?最终结果将是所有选定行的所有URL的列表。 这是我的尝试,但没有给我我想要的东西-这将是所有选定用户的所有href的列表。我只得到一个空的IEnumerations列表。
var all = from bm in MYTABLE
        select new { name=bm.SPP_USER_ID,xml=(string) bm.SPP_BOOKMARKS_XML};

var docs = from x in all
        select XDocument.Parse(x.xml);
var href = from h in docs
        select h.Descendants(\"href\");
解 有两个问题。 -我猜只有在实际需要结果时才执行查询。当我从sql进行到XML查询时,结果查询变成了sql和XML的混合,因此无法执行。我的解决方案是通过将SQL查询转换为结果列表来强制结果。这将linq-sql与linq-xml分开了。
var docs = from x in all
        select XDocument.Parse(x.xml);
var docs2 = docs.ToList();  // force result
-第二个问题是我忘记将名称空间添加到XML查询中。一旦我做到了,我得到了所需的结果
XNamespace ns = \"http://acme/bookmarks\";
var href = from h in docs2
    select h.Descendants(ns + \"href\");
感谢你的帮助!     

解决方法

        这是我尝试过的几件事。 设置:我用表MYTABLE创建了一个数据库,该表包含2列。列1(SPP_USER_ID)是varchar(255),列2(SPP_BOOKMARKS_XML)是xml数据类型。我添加了2行,以反映mellamokb使用的行。我创建了LINQ to SQL设计图并将其拖到该表中。我的应用程序只是一个控制台应用程序,可将LINQ加载到SQL数据上下文中,然后调用您的命令。 我直接针对数据表查询,如下所示:
        var all = from bm in context.MYTABLEs
                  select new { name = bm.SPP_USER_ID,xml = (string)bm.SPP_BOOKMARKS_XML };

        var docs = from x in all
                   select XDocument.Parse(x.xml);

        var href = from h in docs
                   select h.Descendants(\"href\");
结果是IEnumerables的集合。即对于数据库中的每一行,我都有一个IEnumerable,其中包含所有\“ href \”后代。因此,在这种情况下,我得到了两个结果;第一个结果是包含2个元素的IEnumerable,第二个结果是包含1个元素的IEnumerable。从您的描述看来,这至少接近您想要的。但是,可能由于查询的结构方式而看不到期望的结果。 请注意,有时很难使Visual Studio真正向您显示这样的查询结果。我发现我经常不得不“监视”该项目两次,然后才开始触发结果枚举。 我试图复制您的OP中编写的代码,如下所示:
        var MYTABLE = (from bm in context.MYTABLEs select bm).ToList();

        var all = from bm in MYTABLE
                  select new { name = bm.SPP_USER_ID,xml = (string)bm.SPP_BOOKMARKS_XML };

        var docs = from x in all
                   select XDocument.Parse(x.xml);

        var href = from h in docs
                   select h.Descendants(\"href\");
当我这样做时,它导致\“ xml \”值被废弃,因为它已经是一个XDocument(?),因此将其强制转换为字符串会导致所有标记被剥离。因此,接下来的两个语句由于XML解析异常而失败。     ,        这是一个使用您的代码和a6ѭ硬编码内容的代码段,它完美地工作(已通过LinqPad验证)。也许您的数据库表或
MYTABLE
不包含您认为的内容?您可以查看
all
的结果吗?
var MYTABLE = new  [] {
    new {
        SPP_USER_ID = \"XML-SNIPPET-1\",SPP_BOOKMARKS_XML = @\"
        <root>
            <item>
                <href>http://myurl</href>
            </item>
            <item>
                <href>http://myurl2</href>
            </item>
        </root>
        \",},new {
        SPP_USER_ID = \"XML-SNIPPET-2\",SPP_BOOKMARKS_XML = @\"
        <root>
            <item>
                <href>http://google.com</href>
            </item>
        </root>
        \",}
};

var all = from bm in MYTABLE
        select new { name=bm.SPP_USER_ID,xml=(string) bm.SPP_BOOKMARKS_XML};

var docs = from x in all
        select XDocument.Parse(x.xml);
var href = from h in docs
        select h.Descendants(\"href\");

foreach (var h in href.SelectMany(h => h))
{
    Console.WriteLine(h);
}
输出:
<href>http://myurl</href>
<href>http://myurl2</href>
<href>http://google.com</href>
希望这可以帮助!