Commit 66a49521 authored by Marc Gravell's avatar Marc Gravell

Support xml types by default (XmlDocument, XDocument, XElement) - fix #427

parent bd52a790
......@@ -25,7 +25,9 @@
"frameworks": {
"net40": {
"frameworkAssemblies": {
"System.Data": "4.0.0.0"
"System.Data": "4.0.0.0",
"System.Xml": "4.0.0.0",
"System.Xml.Linq": "4.0.0.0"
}
},
"net45": {
......@@ -33,13 +35,16 @@
"define": [ "ASYNC" ]
},
"frameworkAssemblies": {
"System.Data": "4.0.0.0"
"System.Data": "4.0.0.0",
"System.Xml": "4.0.0.0",
"System.Xml.Linq": "4.0.0.0"
}
},
"net451": {
"frameworkAssemblies": {
"System.Data": "4.0.0.0",
"System.Xml": "4.0.0.0"
"System.Xml": "4.0.0.0",
"System.Xml.Linq": "4.0.0.0"
},
"compilationOptions": {
"define": [ "ASYNC" ]
......@@ -62,7 +67,9 @@
"System.Text.RegularExpressions": "4.0.11-*",
"System.Threading": "4.0.11-*",
"System.Threading.ThreadPool": "4.0.10-*",
"System.Collections.NonGeneric": "4.0.1-*"
"System.Collections.NonGeneric": "4.0.1-*",
"System.Xml.XDocument": "4.0.11-*",
"System.Xml.XmlDocument": "4.0.1-*"
}
}
}
......
using System.Xml;
using System.Xml.Linq;
using Xunit;
namespace Dapper.Tests
{
public partial class TestSuite
{
[Fact]
public void CommonXmlTypesSupported()
{
var xml = new XmlDocument();
xml.LoadXml("<abc/>");
var foo = new Foo
{
A = xml,
B = XDocument.Parse("<def/>"),
C = XElement.Parse("<ghi/>")
};
var bar = connection.QuerySingle<Foo>("select @a as [A], @b as [B], @c as [C]", new { a = foo.A, b = foo.B, c = foo.C });
bar.A.DocumentElement.Name.IsEqualTo("abc");
bar.B.Root.Name.LocalName.IsEqualTo("def");
bar.C.Name.LocalName.IsEqualTo("ghi");
}
public class Foo
{
public XmlDocument A { get; set; }
public XDocument B { get; set; }
public XElement C { get; set; }
}
}
}
......@@ -44,7 +44,8 @@
"System.Configuration": "4.0.0.0",
"System.Data": "4.0.0.0",
"System.Data.Linq": "4.0.0.0",
"System.Xml": "4.0.0.0"
"System.Xml": "4.0.0.0",
"System.Xml.Linq": "4.0.0.0"
},
"dependencies": {
"Dapper.EntityFramework": {
......@@ -90,7 +91,8 @@
"System.Data": "4.0.0.0",
"System.Data.Linq": "4.0.0.0",
"System.Runtime": "4.0.0.0",
"System.Xml": "4.0.0.0"
"System.Xml": "4.0.0.0",
"System.Xml.Linq": "4.0.0.0"
},
"dependencies": {
"Dapper.EntityFramework": {
......@@ -129,6 +131,8 @@
"System.Runtime": "4.0.21-*",
"System.Text.RegularExpressions": "4.0.11-*",
"System.Threading": "4.0.11-*",
"System.Xml.XDocument": "4.0.11-*",
"System.Xml.XmlDocument": "4.0.1-*",
"xunit": "2.2.0-beta1-build3239"
}
},
......@@ -157,7 +161,8 @@
"System.Data": "4.0.0.0",
"System.Data.Linq": "4.0.0.0",
"System.Runtime": "4.0.0.0",
"System.Xml": "4.0.0.0"
"System.Xml": "4.0.0.0",
"System.Xml.Linq": "4.0.0.0"
},
"dependencies": {
"Dapper.EntityFramework": {
......@@ -191,6 +196,7 @@
"dependencies": {
"Microsoft.Data.Sqlite": "1.0.0-rc2-15948",
"System.Text.RegularExpressions": "4.0.11-*",
"System.Xml.XmlDocument": "4.0.1-*",
"xunit": "2.2.0-beta1-build3239",
"xunit.runner.dnx": "2.1.0-rc1-build204"
}
......
......@@ -45,5 +45,38 @@ object ITypeHandler.Parse(Type destinationType, object value)
return Parse(value);
}
}
/// <summary>
/// Base-class for simple type-handlers that are based around strings
/// </summary>
public abstract class StringTypeHandler<T> : TypeHandler<T>
{
/// <summary>
/// Parse a string into the expected type (the string will never be null)
/// </summary>
protected abstract T Parse(string xml);
/// <summary>
/// Format an instace into a string (the instance will never be null)
/// </summary>
protected abstract string Format(T xml);
/// <summary>
/// Assign the value of a parameter before a command executes
/// </summary>
/// <param name="parameter">The parameter to configure</param>
/// <param name="value">Parameter value</param>
public override void SetValue(IDbDataParameter parameter, T value)
{
parameter.Value = value == null ? (object)DBNull.Value : Format(value);
}
/// <summary>
/// Parse a database value back to a typed value
/// </summary>
/// <param name="value">The value from the database</param>
/// <returns>The typed value</returns>
public override T Parse(object value)
{
if (value == null || value is DBNull) return default(T);
return Parse((string)value);
}
}
}
}
......@@ -28,6 +28,8 @@
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Xml;
using System.Xml.Linq;
namespace Dapper
{
......@@ -233,6 +235,9 @@ private static void ResetTypeHandlers(bool clone)
typeHandlers = new Dictionary<Type, ITypeHandler>();
#if !COREFX
AddTypeHandlerImpl(typeof(DataTable), new DataTableHandler(), clone);
AddTypeHandlerImpl(typeof(XmlDocument), new XmlDocumentHandler(), clone);
AddTypeHandlerImpl(typeof(XDocument), new XDocumentHandler(), clone);
AddTypeHandlerImpl(typeof(XElement), new XElementHandler(), clone);
try // see https://github.com/StackExchange/dapper-dot-net/issues/424
{
AddSqlDataRecordsTypeHandler(clone);
......
using System.Xml;
using System.Xml.Linq;
namespace Dapper
{
internal sealed class XmlDocumentHandler : SqlMapper.StringTypeHandler<XmlDocument>
{
protected override XmlDocument Parse(string xml)
{
var doc = new XmlDocument();
doc.LoadXml(xml);
return doc;
}
protected override string Format(XmlDocument xml) => xml.OuterXml;
}
internal sealed class XDocumentHandler : SqlMapper.StringTypeHandler<XDocument>
{
protected override XDocument Parse(string xml) => XDocument.Parse(xml);
protected override string Format(XDocument xml) => xml.ToString();
}
internal sealed class XElementHandler : SqlMapper.StringTypeHandler<XElement>
{
protected override XElement Parse(string xml) => XElement.Parse(xml);
protected override string Format(XElement xml) => xml.ToString();
}
}
......@@ -19,7 +19,8 @@
"net40": {
"frameworkAssemblies": {
"System.Data": "4.0.0.0",
"System.Xml": "4.0.0.0"
"System.Xml": "4.0.0.0",
"System.Xml.Linq": "4.0.0.0"
}
},
"net45": {
......@@ -28,13 +29,15 @@
},
"frameworkAssemblies": {
"System.Data": "4.0.0.0",
"System.Xml": "4.0.0.0"
"System.Xml": "4.0.0.0",
"System.Xml.Linq": "4.0.0.0"
}
},
"net451": {
"frameworkAssemblies": {
"System.Data": "4.0.0.0",
"System.Xml": "4.0.0.0"
"System.Xml": "4.0.0.0",
"System.Xml.Linq": "4.0.0.0"
},
"compilationOptions": {
"define": [ "ASYNC" ]
......@@ -46,18 +49,20 @@
},
"dependencies": {
"Microsoft.CSharp": "4.0.1-*",
"System.Runtime": "4.0.21-*",
"System.Collections": "4.0.11-*",
"System.Collections.Concurrent": "4.0.11-*",
"System.Collections.NonGeneric": "4.0.1-*",
"System.Data.SqlClient": "4.0.0-*",
"System.Linq": "4.0.1-*",
"System.Reflection.Emit.ILGeneration": "4.0.1-*",
"System.Reflection.Emit.Lightweight": "4.0.1-*",
"System.Reflection.TypeExtensions": "4.1.0-*",
"System.Runtime": "4.0.21-*",
"System.Text.RegularExpressions": "4.0.11-*",
"System.Threading": "4.0.11-*",
"System.Threading.ThreadPool": "4.0.10-*",
"System.Collections.NonGeneric": "4.0.1-*"
"System.Xml.XDocument": "4.0.11-*",
"System.Xml.XmlDocument": "4.0.1-*"
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment