提交 49e797a4 编写于 作者: M Marc Gravell

Fix #461 - change FindConstructor to allow parameters that have a type-handler defined

上级 1797a3c0
......@@ -138,71 +138,79 @@ public void TestNoDefaultConstructorBinary()
[Fact]
public void Issue461_TypeHandlerWorksInConstructor()
{
// SqlMapper.AddTypeHandler(new Issue461_DateTimeOffsetHandler());
SqlMapper.AddTypeHandler(new Issue461_BlargHandler());
connection.Execute(@"CREATE TABLE #Issue461 (
Id VARCHAR(50),
SomeValue VARCHAR(50),
SomeDateValue DATETIMEOFFSET
Id int not null IDENTITY(1,1),
SomeValue nvarchar(50),
SomeBlargValue nvarchar(200),
)");
var when = new DateTimeOffset(2016, 02, 15, 16, 0, 0, TimeSpan.FromHours(2));
const string Expected = "abc123def";
var blarg = new Blarg(Expected);
connection.Execute(
"INSERT INTO #Issue461 (Id, SomeValue, SomeDateValue) VALUES (@Id, @SomeValue, @SomeDateValue)",
new
{
Id = "id",
SomeValue = "what up?",
SomeDateValue = when
});
"INSERT INTO #Issue461 (SomeValue, SomeBlargValue) VALUES (@value, @blarg)",
new { value = "what up?", blarg });
// test: without constructor
var parameterlessWorks = connection.QuerySingle<Issue461_ParameterlessTypeConstructor>("SELECT * FROM #Issue461");
parameterlessWorks.Id.IsEqualTo("id");
parameterlessWorks.Id.IsEqualTo(1);
parameterlessWorks.SomeValue.IsEqualTo("what up?");
parameterlessWorks.SomeDateValue.IsEqualTo(when);
parameterlessWorks.SomeBlargValue.Value.IsEqualTo(Expected);
//throws about not being able to find constructor (It expects the DateTime field to be a string still)
// test: via constructor
var parameterDoesNot = connection.QuerySingle<Issue461_ParameterisedTypeConstructor>("SELECT * FROM #Issue461");
parameterDoesNot.Id.IsEqualTo("id");
parameterDoesNot.Id.IsEqualTo(1);
parameterDoesNot.SomeValue.IsEqualTo("what up?");
parameterDoesNot.SomeDateValue.IsEqualTo(when);
parameterDoesNot.SomeBlargValue.Value.IsEqualTo(Expected);
}
//class Issue461_DateTimeOffsetHandler : SqlMapper.TypeHandler<DateTimeOffset>
//{
// public override void SetValue(IDbDataParameter parameter, DateTimeOffset value)
// {
// parameter.Value = value.ToString();
// }
class Blarg // I would usually expect this to be a struct; using a class
{ // so that we can't pass unexpectedly due to forcing an unsafe cast - want
// to see an InvalidCastException if it is wrong
public Blarg(string value) { Value = value; }
public string Value { get; }
public override string ToString()
{
return Value;
}
}
class Issue461_BlargHandler : SqlMapper.TypeHandler<Blarg>
{
public override void SetValue(IDbDataParameter parameter, Blarg value)
{
parameter.Value = ((object)value.Value) ?? DBNull.Value;
}
// public override DateTimeOffset Parse(object value)
// {
// return DateTimeOffset.Parse(value.ToString());
// }
//}
public override Blarg Parse(object value)
{
string s = (value == null || value is DBNull) ? null : Convert.ToString(value);
return new Blarg(s);
}
}
class Issue461_ParameterlessTypeConstructor
{
public string Id { get; set; }
public int Id { get; set; }
public string SomeValue { get; set; }
public DateTimeOffset SomeDateValue { get; set; }
public Blarg SomeBlargValue { get; set; }
}
class Issue461_ParameterisedTypeConstructor
{
public Issue461_ParameterisedTypeConstructor(string id, string someValue, DateTimeOffset someDateValue)
public Issue461_ParameterisedTypeConstructor(int id, string someValue, Blarg someBlargValue)
{
Id = id;
SomeValue = someValue;
SomeDateValue = someDateValue;
SomeBlargValue = someBlargValue;
}
public string Id { get; }
public int Id { get; }
public string SomeValue { get; }
public DateTimeOffset SomeDateValue { get; }
public Blarg SomeBlargValue { get; }
}
public class AbstractInheritance
......
......@@ -96,7 +96,7 @@ public ConstructorInfo FindConstructor(string[] names, Type[] types)
if (types[i] == typeof(byte[]) && ctorParameters[i].ParameterType.FullName == SqlMapper.LinqBinary)
continue;
var unboxedType = Nullable.GetUnderlyingType(ctorParameters[i].ParameterType) ?? ctorParameters[i].ParameterType;
if (unboxedType != types[i]
if ((unboxedType != types[i] && !SqlMapper.HasTypeHandler(unboxedType))
&& !(unboxedType.IsEnum() && Enum.GetUnderlyingType(unboxedType) == types[i])
&& !(unboxedType == typeof(char) && types[i] == typeof(string))
&& !(unboxedType.IsEnum() && types[i] == typeof(string)))
......
......@@ -270,6 +270,11 @@ public static void AddTypeHandler(Type type, ITypeHandler handler)
AddTypeHandlerImpl(type, handler, true);
}
internal static bool HasTypeHandler(Type type)
{
return typeHandlers.ContainsKey(type);
}
/// <summary>
/// Configure the specified type to be processed by a custom handler
/// </summary>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册