System.Linq.Dynamic.Core
System.Linq.Dynamic.Core copied to clipboard
DynamicClass Merging base class properties with additional classes
Hi,
I have this example classes:
public class PayData
{
public string Article { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public double Fee{ get; set; }
}
public class Customer
{
public string Name { get; set; }
public int Age { get; set; }
public List<PayData> Paid { get; set; }
}
Now I would like to create a dynamic object that has all properties of Customer and add additional properties, in my case different items of the Paid-list property.
// Fill with custom data...
var customer = new Customer()
{
Age = 18,
Name = "Hans",
Paid = new List<PayData>()
{
new PayData()
{
Name = "Cola",
Article = "213456",
Fee = 1.55,
Id = 1
},
new PayData()
{
Name = "Pepsi",
Article = "d3434",
Fee = 1.25,
Id = 2
},
new PayData()
{
Name = "Wasser",
Article = "4213",
Fee = 0.8,
Id = 3
}
}
};
// The definition would be:
dynamic dynObj = new
{
Article = customer.Article,
Id = customer.Id,
Name = customer.Name ,
Fee = customer.Fee ,
Paid = customer.Paid,
Item = customer.Paid.FirstOrDefault(x => x.Name == "cola")
};
Now I would like to do this in dynamic way using the DynamicClass:
public static DynamicClass GenerateMergedDynamicClass(object obj, IDictionary<string, Tuple<Type, object>> additionalProperties)
{
var propList = new List<DynamicProperty>();
var objType = obj?.GetType();
var objectProperties = objType?.GetProperties();
if (objectProperties != null)
{
propList.AddRange(objectProperties.Select(x => new DynamicProperty(x.Name, x.PropertyType)));
}
if (additionalProperties != null)
{
foreach (var additionalProperty in additionalProperties)
{
if (propList.All(x => x.Name != additionalProperty.Key))
{
propList.Add(new DynamicProperty(additionalProperty.Key, additionalProperty.Value.Item1));
}
}
}
Type type = DynamicClassFactory.CreateType(propList);
var dynamicClass = Activator.CreateInstance(type) as DynamicClass;
if (dynamicClass == null)
{
return null;
}
if (objectProperties != null)
{
var objAccessor = TypeAccessor.Create(objType);
for (int i = 0; i < objectProperties.Length; i++)
{
dynamicClass.SetDynamicPropertyValue(objectProperties[i].Name, objAccessor[obj, objectProperties[i].Name]);
}
}
if (additionalProperties != null)
{
foreach (var additionalProperty in additionalProperties)
{
// ------------ Here the Exception is thrown!!!! ------------------------------
dynamicClass.SetDynamicPropertyValue(additionalProperty.Key, additionalProperty.Value.Item2);
}
}
return dynamicClass;
}
var aditionalObject = customer.Paid.FirstOrDefault(x => x.Name == "cola");
var dynObj = DynamicObjectExtension.GenerateMergedDynamicClass(customer,
new Dictionary<string, Tuple<Type, object>>() {{"Item", new Tuple<Type, object>(typeof(PayData), aditionalObject)}});
var dynExpr = DynamicExpressionParser.ParseLambda(ParsingConfig.Default, dynObj.GetType(), typeof(object), "Name + \" - \" + Item.Article ");
var resultObject = (dynExpr.Compile()).DynamicInvoke(dynObj);
I get the exception when setting the 'Item' property with SetDynamicPropertyValue. If I call the GetProperties method of the DynamicClass type, I get two properties with the name Item.
Hello @Franki1986,
Do you think you could provide a project that compiles which we can run?
It will help my developer investigate the issue more efficiently.
Even if you believe you have provided enough information, we cannot count anymore the number of times someone believes it also, and a third-party package or piece of code was missing, and we were losing hours to reproduce it instead of spending those hours to fix it.
You can send it to: [email protected] if you need to keep the source private Best Regards,
Jonathan
Performance Libraries
context.BulkInsert(list, options => options.BatchSize = 1000);
Entity Framework Extensions • Entity Framework Classic • Bulk Operations • Dapper Plus
Runtime Evaluation
Eval.Execute("x + y", new {x = 1, y = 2}); // return 3
C# Eval Function • SQL Eval Function
@frankiDotNet Is this issue still relevant to you, if so, can you provide a full working dotnetfiddle?
Else I'll close this.