Unable to cast object of type System.Data.Objects.ObjectStateEntryDbUpdatableDataRecord to ComplexType - entity-framework-5

I want to get a string value from an ObjectStateEntry and have the following converter.
My customer class has an address field which is a complex type. However my code fails to handle this.
private static string EntryToString( ObjectStateEntry entry, string fieldName, Context Db)
{
try
{
string fieldValue = "";
int ordinal = 0;
var createdField = entry.CurrentValues.DataRecordInfo.FieldMetadata.FirstOrDefault(f => f.FieldType.Name == fieldName);
var fieldType = createdField.FieldType.TypeUsage.EdmType.Name;
ordinal = createdField.Ordinal;
switch (fieldType)
{
case "String":
fieldValue = entry.CurrentValues[ordinal].ToString();
break;
case "Address"
var obj = entry.CurrentValues[ordinal];
var adr = (Address)obj; // error occurs here
fieldValue = Serialize(adr); // converts to string
break;
// other cases
}
return fieldValue
}
Error message is
System.InvalidCastException: Unable to cast object of type 'System.Data.Objects.ObjectStateEntryDbUpdatableDataRecord' to type '.DomainClasses.Address'.
The domain classes are
public class Customer
{
public Customer()
{
this.Address = new Address();
}
// other fields
}
[ComplexType]
[Serializable]
public class Address
{
public string AddressLine1 { get; set; }
// other fields
}

CurrentValues collection doesn't hold instances of your domain types. It has its own unified representation independent on your domain model so you cannot casts its data type to your types.
If you want to get an address you need to extract it from entry.Entity or create a new instance from information extracted from CurrentValues

Related

Object does not match target type with SetValue using Type

I'm trying to dynamically build set objects based on a user input document. For some reason SetValue is throwing Object does not match target type, despite that it does.
Is what im trying to achieve even possible?
private void MapProp(string prop, string invalue)
{
var currType = _userAssembly.GetType(_className);
var property = currType.GetProperty(prop, BindingFlags.Public | BindingFlags.Instance);
var value = Convert.ChangeType(invalue, property.PropertyType);
property.SetValue(styleType, value, null);
}
}
Currently its attempting to map to said object:
public class TestObject: ITestObj
{
public string PropertyA {get;set;}
public string PropertyB {get;set;}
}
Calling Code
MapProp("PropertyA", "testValue");
and the getType classname = .Assembly.TestObject
#user4550364 ,I dont know what does your _user assembly does ,so I am gonna put my sample code ,this might help you to adapt the idea to your code.This is also an example of late binding.
Class file
public class TestObject: ITestObj
{
public string PropertyA {get;set;}
public string PropertyB {get;set;}
void Print(string PropertyA,string PropertyB)
{
//Assuming that interface ITestObj has this method definition and hence implementing here.
}
}
Main code
using System.Reflection;
static void Main(string[] args)
{
Assembly executingassembly = Assembly.GetExecutingAssembly();
Type TestObjecttype = executingassembly.GetType("ur_namespace.TestObject");
object instance = Activator.CreateInstance(TestObjecttype );
string[] parameters = new string[2];
parameters[0] = "PropertyA ";
parameters[1] = "PropertyB ";
//To get properties
PropertyInfo[] properties = TestObjecttype .GetProperties();
foreach (PropertyInfo property in properties)
{
Console.WriteLine(property.PropertyType.Name+" "+property.Name);
}
MethodInfo method = customertype.GetMethod("Print");
//Object created ,now invoke using its instance
string printMethodInvoked= (string)method.Invoke(instance, parameters);
Console.WriteLine(printMethodInvoked);
Console.Read();
}
}

How to get values of passed in object using C#

I have a following code
public void ShowForm(String EName, String phoneNumber, String dnis, String mode, String callid)
{
objCallParams.EventName = EName;
objCallParams.ANI = phoneNumber;
objCallParams.DNIS = dnis;
objCallParams.Mode = mode;
objCallParams.CallId = callid;
UIThreadContext.Post(InComing_Callback, (object)objCallParams);
}
private void InComing_Callback(object objCallParams)
{
/*want to access phone number i.e.objCallParams.ANI*/
}
How do I access phoneNumber in InComing_Callback(object objCallParams) method?
If you know the type of the object you can use casting
private void InComing_Callback(object objCallParams)
{
// If you know that objCallParams will always be of the type FormParameters:
var params = (FormParameters)objCallParams;
// if you are not so sure about that
var notSoSureParams = objCallParams as FormParameters;
if (notSoSureParams != null)
{
}
}

Automapper error: Expressions mapping from methods not supported yet

Any idea what might cause the error "Expressions mapping from methods not supported yet." when trying to map two objects? I cannot find any reference to this error anywhere.
EDITED---
I have more information. I have a property in my DTO declared as:
public LookupItem RegionType { get; set; }
However, when I invoke the mapping, it generates the error, "Expressions mapping from methods not supported yet.".
However, if I change the string in the property name "Type" to anything else like "Typeo" or "ASDF", the mapping succeeds. In other words, if change the property name to "RegionTypeo". Am I breaking any convention rules here? There seems to be something wrong with including the string "Type" in my property name.
Below is the generated error:
Result Message:
Test method Rep.Tests.PlanServiceTest.GetBuildings threw exception:
System.NotImplementedException: Expressions mapping from methods not supported yet.
Result StackTrace:
at AutoMapper.PropertyMap.ResolveExpression(Type currentType, Expression instanceParameter)
at AutoMapper.QueryableExtensions.Extensions.CreateMemberBindings(IMappingEngine mappingEngine, Type typeIn, TypeMap typeMap, Expression instanceParameter)
at AutoMapper.QueryableExtensions.Extensions.CreateMapExpression(IMappingEngine mappingEngine, Type typeIn, Type typeOut, Expression instanceParameter)
at AutoMapper.QueryableExtensions.Extensions.CreateMapExpression(IMappingEngine mappingEngine, Type typeIn, Type typeOut)
at AutoMapper.QueryableExtensions.Extensions.<>c__DisplayClass12.<CreateMapExpression>b__0(TypePair tp)
at System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func2 valueFactory)
at AutoMapper.Internal.DictionaryFactoryOverride.ConcurrentDictionaryImpl2.GetOrAdd(TKey key, Func2 valueFactory)
at AutoMapper.QueryableExtensions.Extensions.CreateMapExpression[TSource,TDestination](IMappingEngine mappingEngine)
at AutoMapper.QueryableExtensions.ProjectionExpression1.ToTResult
at Rep.Services.PlanService.GetBuildings() in c:\Dev\REP\Rep\Services\PlanService.cs:line 369
at Rep.Tests.PlanServiceTest.GetBuildings() in c:\Dev\REP\Rep.Tests\PlanServiceTest.cs:line 50
Based on the source code, you can see that the exception is thrown when you try mapping functions on your objects:
public ExpressionResolutionResult ResolveExpression(Type currentType, Expression instanceParameter)
{
Expression currentChild = instanceParameter;
Type currentChildType = currentType;
foreach (var resolver in GetSourceValueResolvers())
{
var getter = resolver as IMemberGetter;
if (getter != null)
{
var memberInfo = getter.MemberInfo;
var propertyInfo = memberInfo as PropertyInfo;
if (propertyInfo != null)
{
currentChild = Expression.Property(currentChild, propertyInfo);
currentChildType = propertyInfo.PropertyType;
}
else
{
throw new NotImplementedException("Expressions mapping from methods not supported yet.");
}
}
else
{
var oldParameter = CustomExpression.Parameters.Single();
var newParameter = instanceParameter;
var converter = new ConversionVisitor(newParameter, oldParameter);
currentChild = converter.Visit(CustomExpression.Body);
currentChildType = currentChild.Type;
}
}
return new ExpressionResolutionResult(currentChild, currentChildType);
}
Based on OP clarification, I cannot reproduce the problem with the following:
public class Class1
{
public string StringType { get; set; }
public Func<Class1> FuncType { get; set; }
public Class1 Class1Type { get; set; }
}
public class Class2
{
public string StringType { get; set; }
public Func<Class1> FuncType { get; set; }
public Class1 Class1Type { get; set; }
}
/* ... */
AutoMapper.Mapper.CreateMap<Class1, Class2>();
var c1 = new Class1() { Class1Type = new Class1(), FuncType = () => new Class1(), StringType = "Class1" };
var c2 = AutoMapper.Mapper.Map<Class1, Class2>(new Class1());

Get property values from a string using Reflection

I am new to this concept of reflection and finding problem in retrieving property value from a string. E.g.
I have a class Employee with following properties :
public string Name {get;set;}
public int Age {get;set;}
public string EmployeeID {get;set;}
string s = "Name=ABCD;Age=25;EmployeeID=A12";
I want to retrieve the value of each property from this string and create a new object of Employee with those values retrieved from the string for each field.
Can anyone please suggest how it can be done using reflection ??
//may be..
string s = "Name=ABCD;Age=25;EmployeeID=A12";
string[] words = s.Split(';');
foreach (string word in words)
{
string[] data = word.Split('=');
string _data = data[1];
Console.WriteLine(Name);
}
Here an example of how you maybe could do it
it used Reflection like you wanted ^^
using System;
using System.Collections.Generic;
using System.Reflection;
namespace replace
{
public class Program
{
private static void Main(string[] args)
{
var s = "Name=ABCD;Age=25;EmployeeID=A12";
var list = s.Split(';');
var dic = new Dictionary<string, object>();
foreach (var item in list)
{
var probVal = item.Split('=');
dic.Add(probVal[0], probVal[1]);
}
var obj = new MyClass();
PropertyInfo[] properties = obj.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
Console.WriteLine(dic[property.Name]);
if (property.PropertyType == typeof(Int32))
property.SetValue(obj, Convert.ToInt32(dic[property.Name]));
//else if (property.PropertyType== typeof(yourtype))
// property.SetValue(obj, (yourtype)dic[property.Name]);
else
property.SetValue(obj, dic[property.Name]);
}
Console.WriteLine("------------");
Console.WriteLine(obj.Name);
Console.WriteLine(obj.Age);
Console.WriteLine(obj.EmployeeID);
Console.Read();
}
}
public class MyClass
{
public string Name { get; set; }
public int Age { get; set; }
public string EmployeeID { get; set; }
}
}

create sort on list for web API controller

I am writing my first web API controller so I am a bit of a noob in this area. I am trying to retrieve a list of data through a static class called CustomerDataSource:
public static class CustomerDataSource
{
public static List<Customer> customerData
{
get
{
Customer customer1 = new Customer() { name = "Bert", address = "London" };
Customer customer2 = new Customer() { name = "Jon", address = "New York" };
List<Customer> listCustomers = new List<Customer>();
listCustomers.Add(customer1);
listCustomers.Add(customer2);
return listCustomers;
}
}
}
public class Customer
{
public string name { get; set; }
public string address { get; set; }
}
I am a bit stuck with my ApiController because I am trying to sort the list either on 'name' or 'address' but using a string called 'field' does not compile. What would be a good implementation for a WebAPI controller GETmethod which provides for sorting on one of the Customer properties ?
public class ValuesController : ApiController
{
// GET api/values
public List<Customer> Get(string field)
{
var list = CustomerDataSource.customerData.OrderBy(field);
}
}
Create an extension method like below, then you can use it anywhere within the same namespace in your project.
public static class extensionmethods
{
public static IQueryable<T> OrderByPropertyName<T>(this IQueryable<T> q, string SortField, bool Ascending)
{
var param = Expression.Parameter(typeof(T), "p");
var prop = Expression.Property(param, SortField);
var exp = Expression.Lambda(prop, param);
string method = Ascending ? "OrderBy" : "OrderByDescending";
Type[] types = new Type[] { q.ElementType, exp.Body.Type };
var rs = Expression.Call(typeof(Queryable), method, types, q.Expression, exp);
return q.Provider.CreateQuery<T>(rs);
}
}
Then you can use it like:
public List<Customer> Get(string PropertyName)
{
var list = CustomerDataSource.customerData.AsQueryable().OrderByPropertyName("PropertyName",true).ToList();
}
Note:
Because the extension method uses IQueryable and returns IQuerybale, so you need to convert your List to IQueryable. Also you can order the list by ascending and descending order, just pass the boolean type value to the second parameter. The default is ascending.
You need to use a lambda expression.
if (field == "name")
var list = CustomerDataSource.customerData.OrderBy(d => d.name);
else if (field == "address")
var list = CustomerDataSource.customerData.OrderBy(d => d.address);

Resources