使用Dapper从数据库中检索XML

时间:2014-11-18 04:22:06

标签: dapper

我正在使用Dapper查询包含XML字段的表:

CREATE TABLE Workflow
(
    Guid uniqueidentifier not null,
    State xml not null
)

然后映射到XDocument类型的属性:

public class Workflow
{
    public Guid InstanceId { get;set; }
    public XDocument State { get;set; }
}

但是当我尝试查询表时,出现以下错误:

Error parsing column 1 (State= - String)
   at Dapper.SqlMapper.ThrowDataException(Exception ex, Int32 index, IDataReader reader, Object value) in d:\\Dev\\dapper-dot-net\\Dapper NET40\\SqlMapper.cs:line 4045
   at Deserialize038b29f4-d97d-4b62-b45b-786bd7d50e7a(IDataReader )
   at Dapper.SqlMapper.<QueryImpl>d__11`1.MoveNext() in d:\\Dev\\dapper-dot-net\\Dapper NET40\\SqlMapper.cs:line 1572
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Dapper.SqlMapper.Query[T](IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Boolean buffered, Nullable`1 commandTimeout, Nullable`1 commandType) in d:\\Dev\\dapper-dot-net\\Dapper NET40\\SqlMapper.cs:line 1443
   at MyProject.DapperBase.Query[TResult](String command, DynamicParameters parameters, IDbTransaction transaction, Boolean buffered, Int32 commandTimeout) in d:\\MyProject\\DapperBase.cs:line 122
   at MyProject.WorkflowData.Get(Guid identifier) in d:\\MyProject\\WorkflowData.cs:line 41
   at MyProject.WorkflowLogic.Save(Workflow workflow) in d:\\MyProject\\WorkflowLogic.cs:line 34
   at MyProject.WorkflowsController.Save(Guid id, WorkflowRequest request) in d:\\MyProject\\WorkflowsController.cs:line 97

InnerException: Invalid cast from 'System.String' to 'System.Xml.Linq.XDocument'.
    at System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)at System.String.System.IConvertible.ToType(Type type, IFormatProvider provider)
    at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
    at System.Convert.ChangeType(Object value, Type conversionType)
    at Deserialize038b29f4-d97d-4b62-b45b-786bd7d50e7a(IDataReader )

除了修改我的POCO以使用字符串数据类型然后将字符串转换为其他地方的XDocument之外,有没有办法让Dapper正确地从数据库中反序列化XML?

2 个答案:

答案 0 :(得分:2)

也许创建自定义类型处理程序可以帮助吗?类似的东西:

public class XDocumentTypeHandler : SqlMapper.TypeHandler<XDocument>
{
    public override void SetValue(IDbDataParameter parameter, XDocument value)
    {
       // set value in db parameter.
    }

    public XDocument Parse(object value)
    {
       // parse value from db to an XDocument.
    }
}

您必须使用SqlMapper.AddTypeHandler()添加类型处理程序。

请参阅the introducing blogpost博客帖子和sample implementation

答案 1 :(得分:2)

最后,我只是粗暴地强迫它:

public class Workflow
{
    public Guid InstanceId { get;set; }
    public XDocument StateIn { set { State = value.ToString(); } }
    public string State { get;set; }
    public XDocument StateOut { get { return XDocument.Parse(State); } }
}

Dapper播放State值,我只是在StateIn上设置值并将其从StateOut中读取。我觉得有点脏,想出这样的解决方案,但是嘿,它有效。