【问题标题】:Dapper Deserializing XMLDapper 反序列化 XML
【发布时间】:2012-10-31 05:42:42
【问题描述】:

如果我将 XML 存储在 nvarchar 中,Dapper(或 Dapper 扩展)是否可以将 XML 反序列化为 DataContract 类型或带有 XmlRoot / XmlElement 注释的类型?

如果不直接处理,有没有这样的成语?例如,也许我的目标 DataContract 类具有 Dapper 尝试设置的属性,并且该属性执行字符串的反序列化?

【问题讨论】:

    标签: c# .net serialization orm dapper


    【解决方案1】:

    我认为Dapper在v1.50.5(或更早版本)已经有supportsXML数据类型,它可以将XML数据类型转换为XmlDocumentXDocumentXElement

    它确实在我的代码中将XML 数据类型转换为XElement

    2021 年 3 月 5 日的示例代码

    返回 XML 类型数据的存储过程:

    CREATE PROCEDURE spGetCarInformation
    AS
    DECLARE @Cfg XML
    SET @Cfg = '<Configuration>
        <A>111</A>
        <B>222</B>
    </Configuration>'
    
    SELECT 1 AS Id, 'Test' AS Name, @Cfg AS [Configuration]
    

    代码示例:

    /* Program.cs */
    
    using System;
    using System.Linq;
    using System.Xml.Linq;
    using Microsoft.Data.SqlClient;
    using Dapper;
    
    namespace ConsoleApp
    {
        class Program
        {
            static void Main(string[] args)
            {
                /* query XML data from database */
                using var connection = new SqlConnection("Data Source=; Initial Catalog=; User ID=; Password=");
                Car car = connection.Query<Car>("EXEC spGetCarInformation").First();
                Console.WriteLine(car.Name);
                Console.WriteLine(car.Configuration.Element("A").Value);
                Console.WriteLine(car.Configuration.Element("B").Value);
    
                /* Insert XML data into database */
                car = new Car
                {
                    Id = 2,
                    Name = "New Car",
                    Configuration = new XElement
                    (
                        "Configuration",
                        new XElement("A", "333"),
                        new XElement("B", "444")
                    )
                };
    
                string cmdText = @"CREATE TABLE #Car
    (
        Id INT,
        Name NVARCHAR(128),
        Configuration XML
    )
    
    INSERT INTO #Car
    VALUES
        (@Id, @Name, @Configuration)
        
    SELECT * FROM #Car
    
    DROP TABLE #Car";
    
                Car result = connection.Query<Car>(cmdText, car).First();
                Console.WriteLine(result.Name);
                Console.WriteLine(result.Configuration.Element("A").Value);
                Console.WriteLine(result.Configuration.Element("B").Value);
            }
        }
    
        class Car
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public XElement Configuration { get; set; }
        }
    }
    
    

    输出:

    项目中添加的 Nuget 包:

    <PackageReference Include="Dapper" Version="2.0.78" />
    <PackageReference Include="Microsoft.Data.SqlClient" Version="2.1.2" />
    

    我在 .NET 5 上测试了代码,但应该也可以在 .Net Framework 4.7.2+ 和 System.Data.SqlClient 上运行。

    【讨论】:

    • Ricky,你能提供一个简单/小的工作代码示例吗?在我的代码中,Dapper 为 XML 类型的字段返回 null,而预期的正确结果将是 XElement 的实例。
    • 谢谢你,瑞奇。 +1。反过来的代码示例怎么样:将 Car 实例写入数据库中的表中,该表具有 XML 类型的 Car 列?
    【解决方案2】:

    不,目前它不会尝试对此进行任何特殊处理,除非将其分配给与列名匹配的字符串属性。现在,我建议简单地:将“获取数据”和“将数据反序列化为对象”步骤分开。这也许可以被视为附加功能,但目前还不存在。

    【讨论】:

    • Dapper 是否支持xml 数据类型?
    • 查看SqlMapper.cs (line 687) 的答案,目前是“否”。
    • Marc Gravell,今天(2021 年 3 月 2 日)情况如何?当我有一个字符串属性和一个具有相应名称的 XElement 属性时,我都得到一个空值。我向团队建议更改 SP 以将 XML 作为字符串返回。这是最好的解决方案吗?
    猜你喜欢
    • 2016-01-12
    • 2016-12-03
    • 2012-03-04
    • 2011-03-03
    • 1970-01-01
    相关资源
    最近更新 更多