Simplification :
We have our own DB mapper from SqlDataReader to Entity.
In normal circumstances, this is the case :
void Main()
{
object s = (int?)1;
MyClass newObjectToReturn = Activator.CreateInstance<MyClass>();
typeof(MyClass).InvokeMember("MyProperty", BindingFlags.SetProperty, null, newObjectToReturn, new Object[] { s });
}
class MyClass
{
public int? MyProperty { get; set; }
}
One thing to mention is that this line :
object s = (int?)1;
Is here to simulate the SqlDataReader which wraps the value as Object. In debug, I see it as Object{int}
All Ok and works.
So where is the problem?
The problem is that the type in DB is smallint
, which is a Short
in C# , and the type in the entity is an int?
So basically what's happening is this :
object s = (short?)1;
int? MyProperty = (int?)s;
Which yields to exception :
Method 'UserQuery+MyClass.MyProperty' not found.
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
at System.Type.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args)
at UserQuery.Main() in C:\Users\royin\AppData\Local\Temp\LINQPad5\_oexzmkdz\query_deibtt.cs:line 33
at LINQPad.ExecutionModel.ClrQueryRunner.Run()
at LINQPad.ExecutionModel.Server.RunQuery(QueryRunner runner)
at LINQPad.ExecutionModel.Server.StartQuery(QueryRunner runner)
at LINQPad.ExecutionModel.Server.<>c__DisplayClass153_0.<ExecuteClrQuery>b__0()
at LINQPad.ExecutionModel.Server.SingleThreadExecuter.Work()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
I already know how to solve it :
It's by changing :
typeof(MyClass).InvokeMember("MyProperty", BindingFlags.SetProperty, null, newObjectToReturn, new Object[] { s });
to
typeof(MyClass).InvokeMember("MyProperty", BindingFlags.SetProperty, null, newObjectToReturn, new Object[] { (int?)(short?)s });
// btw , this also works : `(int?)(dynamic)s`
Question:
How can I cast
s
to the entity's property type ?
(int?)(short?)s
I already know how to get type from the property :
newObjectToReturn.GetType().GetProperties().Where(otr =>otr.Name== "MyProperty").First().PropertyType
but how can I cast s to this ^ ?
Aucun commentaire:
Enregistrer un commentaire