In an application we have we have a set of ORM objects, and a set of business object. Most of the time we're simply doing a member by member copy. Other times we process the data slightly. For instance:
tEmployee emp = new tEmployee();
emp.Name = obj.Name;
emp.LastName = obj.LastName;
emp.Age = obj.Age;
emp.LastEdited = obj.LastEdited.ToGMT();
Now this works just fine, and is rather fast, but not exactly terse when it comes to coding. Some of our objects have upto 40 members, so doing a copy like this can get rather tedious. Granted you only need 2 methods for two->from conversion, but I'd like to find a better way to do this.
Reflection is an natural choice, but on a benchmark I found that execution time was about 100x slower when using reflection.
Is there a better way to go about this?
Clarification:
I'm converting from one type to another. In the above example obj is of type BLogicEmployee and emp is of type tEmployee. They share member names, but that is it.
You might want to check out AutoMapper.
If you don't mind it being a bit slow the first time you can compile a lambda expression:
public static class Copier<T>
{
private static readonly Action<T, T> _copier;
static Copier()
{
var x = Expression.Parameter(typeof(T), "x");
var y = Expression.Parameter(typeof(T), "y");
var expressions = new List<Expression>();
foreach (var property in typeof(T).GetProperties())
{
if (property.CanWrite)
{
var xProp = Expression.Property(x, property);
var yProp = Expression.Property(y, property);
expressions.Add(Expression.Assign(yProp, xProp));
}
}
var block = Expression.Block(expressions);
var lambda = Expression.Lambda<Action<T, T>>(block, x, y);
_copier = lambda.Compile();
}
public static void CopyTo(T from, T to)
{
_copier(from, to);
}
}
Reflection can be sped up an awful lot if you use delegates. Basically, you can create a pair of delegates for each getter/setter pair, and then execute those - it's likely to go very fast. Use Delegate.CreateDelegate to create a delegate given a MethodInfo etc. Alternatively, you can use expression trees.
If you're creating a new object, I already have a bunch of code to do this in MiscUtil. (It's in the MiscUtil.Reflection.PropertyCopy class.) That uses reflection for properties to copy into existing objects, but a delegate to convert objects into new ones. Obviously you can adapt it to your needs. I'm sure if I were writing it now I'd be able to avoid the reflection for copying using Delegate.CreateDelegate, but I'm not about to change it :)
Consider using AutoMapper. From its documentation:
.. AutoMapper works best as long as
the names of the members match up to
the source type's members. If you have
a source member called "FirstName",
this will automatically be mapped to a
destination member with the name
"FirstName".
This will save you a great deal of explicit mapping, and AutoMapper of course allows for the customization of particular mappings along the lines of:
Mapper.CreateMap<Model.User, Api.UserInfo>()
.ForMember(s => s.Address, opt => opt.Ignore())
.ForMember(s => s.Uri, opt => opt.MapFrom(c => HttpEndpoint.GetURI(c)))
Object.MemberwiseClone might be useful if all you need is a shallow clone. Not sure how well it performs though, and obviously any complex objects would need additional handling to ensure a proper copy.
See if you can use this
RECAP:
and class must be Serializable for this to work.
public static T DeepClone<T>(T obj)
{
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
ms.Position = 0;
return (T) formatter.Deserialize(ms);
}
}
Look att Automapper it can autmatically map your objects if your fields match...
http://automapper.codeplex.com/
Related
Trying to write a piece of code that is dynamic in that it can accept any number of possible model definitions.
Current hard code is:
var items = _context.Events.ToList();
foreach (var item in items)
{
(...)
}
What I would like to do is to make the _context.Events.ToList(); be more like _context.{variable that holds model name}.ToList();
Something like:
var modelName = "Table1"
var items = _context.modelName.ToList();
foreach (var item in items)
{
(...)
}
I thought about declaring items as a generic variable, that way it was available to the entire method even if set inside an if or switch, but no idea on what to declare it as.
Is something like this possible?
Try this :
var table = (ITable)context.GetType()
.GetProperty(modelName)
.GetValue(context, null);
I hope be helpful :)
Entity Framework has a generic Set<TEntity> accessor, but the type must be known at compile-time:
var foo = _context.Set<Foo>();
If you have the type as a string variable, though, your options are extremely limited. You can technically use reflection to get at the right DbSet, but you're going to lose the generic IQueryable<TEntity> interface, and you'll be stuck with the much more limited IQueryable interface, and by "much more limited", I mean you basically can't do anything but materialize the set.
If you want to type it via a string variable, but still have at least some querying ability, you'll need to employ a base class that's shared between all the entity types you'd want to use in this way. For example, if you have different "event" types, and you can make them all inherit from Event, then you could do something like:
MethodInfo method = typeof(Queryable).GetMethod("OfType");
MethodInfo generic = method.MakeGenericMethod(new Type[] { eventType });
var set = (IQueryable<Event>)generic.Invoke(null, new object[] { _context.Events });
If your eventType was "Film", for example, that would effectively give you the same queryset as something like _context.Set<Film>() (where Film would be a derived class of Event). You could then utilize your normal LINQ query functionality like Where, Select, etc. on set.
I'm learning the power of generics in C# in conjunction with NHibernate. I'd like to attempt the following in the pasted code.
In an attempt to do some post processing of N number of NHibernate objects I worked on a utility method leveraging generics to make it applicable to all NHibernate mapping classes we use now, or in the future. It works but I need to hard code each call for each mapping class. This is a pain and will need continuing updating as our schema and mappings change over time.
I do have an ever up-to-date list of all mapping classes by string name through the NHibernate mappings I generate on the fly. If there was a way to use this list of string names to call my generics based method, I'd be super happy.
Can anyone tell me if this is possible? Do I need to find another route?
Thanks so much in advance!!!
public static void ProcessSomeItems()
{
// *************************************************************
// As of now I have to list all classes as such to be processed
// It works but I have to update manually when new mapping classes are created
// *************************************************************
NHibDoSomethingUtil<AspnetMembership>();
NHibDoSomethingUtil<AspnetProfile>();
NHibDoSomethingUtil<AspnetRole>();
NHibDoSomethingUtil<AspnetUser>();
// and so forth...
// I have a up-to-date list of all mappings from "HbmMapping" and can get a list of all in the
// list form as below
List<string> mappingNames = new List<string>();
foreach (string mappingName in mappingNames)
{
Type theType = Type.GetType(mappingName);
// I know I'm getting Types and Generics classes and so forth all jumbled but
// how in the heck would I do something like the below?
NHibDoSomethingUtil<theType>(); // Obviously doesn't compile ;-)
}
}
// Generic method
public static void NHibDoSomethingUtil<T>() where T : class
{
using (ISession session = sourceDBSessionFactory.OpenSession())
{
foreach (dynamic item in new List<T>(session.QueryOver<T>().List()))
{
// Process item;
}
}
}
ecsousa gave great input and I was able to accomplish what I needed with something like the following.
foreach (HbmClass mappingClass in mapping.Items)
{
Console.WriteLine(" -- Discovered Mapping: " + mappingClass.Name);
Type mappingClassType = Type.GetType(mappingClass.Name);
var genericMethod = typeof(Migration).GetMethod("NHibDoSomethingUtil");
var method = genericMethod.MakeGenericMethod(mappingClassType);
method.Invoke(null, null);
}
You will need to use Reflection in order to accomplish this. Instead of directly calling NHibDoSomethingUtil, try this:
var genericMethod = typeof(TheClassName).GetMethod("NHibDoSomethingUtil");
var method = genericMethod.MakeGenericMethod(theType);
method.Invoke(null, null);
Note that you have to replace TheClassName by the class containing both methods.
Keep in mind the this kind of code is slow, and you should use it very carefully.
When working with IQuerayble<TItem> we can call Select like this:
query.Select( item => new { A=item.Prop1, B=item.Prop2});
And Select method expects Expression<Func<TItem,TResult>>
I need to use ExpandoObject instead of anonymous but statically typed class.
If it were possible it would look like:
query.Select( item => dynamic new ExpandoBoject { A=item.Prop1, B=item.Prop2});
So I want to construct expression tree Expression<Func<TItem,ExpandoObject>> where object's properties are initialized in the similar way as with anonymous type.
Dynamic functionality is only needed for initialization so it's ok that Func returns ExpandoObject instead of dynamic.
I cannot find much documentation about Expression.Dynamic and corresponding binders I should use.
Update 1
Why do I need all this stuff?
Because I want to get primary keys.
I want to do it for any entity type.
I know how to get the list of the properties composing PK, but now I need to make a tricky projection of the entity to EntityKey. Well, may be to same equvalent of this class.
var keys = context.Set<TEntity>().Where(Expression<Func<TEntity,bool>).Select(Expression<Func<TEntity,EntityKey>>);
As I noted in the comments lambdas containing blocks cannot be converted to expression trees so i cannot simple create the dictionary and fill it. Now I'm playing with the expression tree semantically close to this code:
var dict = new Dictionary<string,object>();
dict.Add("Prop1",value1);
dict.Add("Prop2",value2);
return dict
But I doubt EF can parse the expression containing blocks. Need to check.
And I'm curious whether it will work with dynamic objects and Expression.MemberInit as it works with static objects.
Update 2
Entity Framework does not support dictionary initialization syntax.
It throws NotSupportedException with the message: Only list initializer items with a single element are supported in LINQ to Entities.
Update 3
EF does not support block expressions aswell.
NotSupportedException with message: Unknown LINQ expression of type 'Block'.
Now I'm playing with the expression tree semantically close to this code:
var dict = new Dictionary<string,object>();
dict.Add("Prop1",value1);
dict.Add("Prop2",value2);
return dict;
You can do that, because you can write that code as as a single expression like this:
new Dictionary<string, object>
{
{ "Prop1", value1 },
{ "Prop2", value2 }
};
And you can create an expression tree that contains this expression (which EF should be able to handle) like this:
var addMethod = typeof(Dictionary<string, object>).GetMethod("Add");
var expression = Expression.Lambda<Func<Dictionary<string, object>>>(
Expression.ListInit(
Expression.New(typeof(Dictionary<string, object>)),
Expression.ElementInit(
addMethod,
Expression.Constant("Prop1"),
value1Expression),
Expression.ElementInit(
addMethod,
Expression.Constant("Prop2"),
value2Expression)),
itemParameterExpression);
The described thing is difficult mainly because we cannot create anonymous type dynamically at run time - they need to be known already at compile time. So my proposition is to create a class that may hold several properties of arbitrary chosen type (similar to Tuple), however we will load from db values only for properties important for us. So we need class like this:
public class CustomTuple<T1, T2>
{
public T1 Item1 { get; set; }
public T2 Item2 { get; set; }
}
We may add there more properties if we need more. If we would have such class with 5 properties that with use of it we may load at max 5 properties. Now the projection logic:
Type[] parameterTypes = new Type[] { typeof(int), typeof(object) };
Type tupleType = typeof(CustomTuple<,>).MakeGenericType(parameterTypes);
ParameterExpression x = Expression.Parameter(typeof(Entity));
NewExpression body = Expression.New(tupleType.GetConstructor(new Type[0]), new Expression[0]);
MemberBinding binding1 = Expression.Bind(
typeof(CustomTuple<,>).MakeGenericType(parameterTypes).GetProperty("Item1"),
Expression.Property(x, "Value"));
MemberInitExpression memberInitExpression =
Expression.MemberInit(
body,
binding1);
Expression<Func<Entity, object>> exp = Expression.Lambda<Func<Entity, object>>(memberInitExpression, x);
using (MyDbContext context = new MyDbContext())
{
var list = context.Entities.Select(exp).ToList();
}
The above code selects from Entities collection values of Entity class Value property. parameterTypes defines types of parameters returned from Select projection. If we do not intend to use given property then we leave it as of object type. Then we need to build initialization expression. We do this with method New, we assign the properties values with expression created by Expression.Bind and we combine them together with Expression.MemberInit. We may dynamically create at run time as much MemberBinding expressions as we need.
So I have thousands of objects, of generic type T, and I want to cast them to an array of objects I got.
So I have to get the properties list T, and for each property set the value to the corresponding object on the array
for (int i = 0; reader.Read(); i++)
{
T tmp = (T)Activator.CreateInstance(typeof(T));
foreach (var prop in properties)
{
prop.SetValue(tmp, reader.GetValue(reader.GetOrdinal(prop.Name)), null);
}
}
reader is a DataReader. The problem I have is that prop.SetValue is sadly slow (consumes like 50% of the total excecution time), I've been told to use Dynamic Methods or Expression Trees, I tried using expression trees but from what I understood I have to generate one tree for each value I want to set, which wouldn't be so good.
So Dynamic Methods is the other option. Ideally I'd need to create a method SetProp(object, propertyName, value) which I can reuse over and over again.
Look at FastMember; either use it "as is", or steal all the code (DynamicMethod, etc). It does all this, with reflection-cache etc built in. Example usage:
var accessor = TypeAccessor.Create(typeof(T));
for (int i = 0; reader.Read(); i++)
{
T tmp = (T)Activator.CreateInstance(typeof(T));
foreach (var prop in properties)
{
accessor[tmp, propName] = newValue; // fill in name/value here
}
}
alternatively - use something like dapper-dot-net, that does that and handles all the materialization (since this is obviously data-access code).
I tried using expression trees but from what I understood I have to generate one tree for each value I want to set, which wouldn't be so good.
Why not? You'd basically build a List<Tuple<string, Action<object>>> by creating (and then compiling) an expression tree for each property in T. Then you iterate over the list and fetch the item for each property, then call the corresponding action.
I have a PropertyCopy class in MiscUtil which does something very similar - you may want to look at that for inspiration.
Alternatively, as of .NET 4 you could build a single Block expression tree which does all the property setting.
You can create a single expression tree for each property.
Just take the value as a parameter:
var instance = Expression.Parameter(typeof(T));
var value = Expression.Parameter(typeof(object));
var setter = Expression.Lambda(
Expression.SetProperty(instance, Expression.Cast(value, prop.PropertyType)),
instance, value
);
You would create and compile these expression trees once per instance type (typically in a static generic class).
While you're at it, you can probably make it even faster by compiling another expression tree instead of Activator.CreateInstance().
Following are two examples that do the same thing in different ways. I'm comparing them.
Version 1
For the sake of an example, define any method to create and return an ExpandoObject from an XElement based on business logic:
var ToExpando = new Func<XElement, ExpandoObject>(xClient =>
{
dynamic o = new ExpandoObject();
o.OnlineDetails = new ExpandoObject();
o.OnlineDetails.Password = xClient.Element(XKey.onlineDetails).Element(XKey.password).Value;
o.OnlineDetails.Roles = xClient.Element(XKey.onlineDetails).Element(XKey.roles).Elements(XKey.roleId).Select(xroleid => xroleid.Value);
// More fields TBD.
}
Call the above delegate from a LINQ to XML query:
var qClients =
from client in xdoc.Root.Element(XKey.clients).Elements(XKey.client)
select ToExpando(client);
Version 2
Do it all in the LINQ query, including creation and call to Func delegate.
var qClients =
from client in xdoc.Root.Element(XKey.clients).Elements(XKey.client)
select (new Func<ExpandoObject>(() =>
{
dynamic o = new ExpandoObject();
o.OnlineDetails = new ExpandoObject();
o.OnlineDetails.Password = client.Element(XKey.onlineDetails).Element(XKey.password).Value;
o.OnlineDetails.Roles = client.Element(XKey.onlineDetails).Element(XKey.roles).Elements(XKey.roleId).Select(xroleid => xroleid.Value);
// More fields TBD.
return o;
}))();
Considering delegate creation is in the select part, is Version 2 inefficient? Is it managed or optimized by either the C# compiler or runtime so it won't matter?
I like Version 2 for its tightness (keeping the object creation logic in the query), but am aware it might not be viable depending on what the compiler or runtime does.
The latter approach looks pretty horrible to me. I believe it will have to genuinely create a new delegate each time as you're capturing a different client each time, but personally I wouldn't do it that way at all. Given that you've got real statements in there, why not write a normal method?
private static ToExpando(XElement client)
{
// Possibly use an object initializer instead?
dynamic o = new ExpandoObject();
o.OnlineDetails = new ExpandoObject();
o.OnlineDetails.Password = client.Element(XKey.onlineDetails)
.Element(XKey.password).Value;
o.OnlineDetails.Roles = client.Element(XKey.onlineDetails)
.Element(XKey.roles)
.Elements(XKey.roleId)
.Select(xroleid => xroleid.Value);
return o;
}
and then query it with:
var qClients = xdoc.Root.Element(XKey.clients)
.Elements(XKey.client)
.Select(ToExpando);
I would be much more concerned about the readability of the code than the performance of creating delegates, which is generally pretty quick. I don't think there's any need to use nearly as many lambdas as you currently seem keen to do. Think about when you come back to this code in a year's time. Are you really going to find the nested lambda easier to understand than a method?
(By the way, separating the conversion logic into a method makes that easy to test in isolation...)
EDIT: Even if you do want to do it all in the LINQ expression, why are you so keen to create another level of indirection? Just because query expressions don't allow statement lambdas? Given that you're doing nothing but a simple select, that's easy enough to cope with:
var qClients = xdoc.Root
.Element(XKey.clients)
.Elements(XKey.client)
.Select(client => {
dynamic o = new ExpandoObject();
o.OnlineDetails = new ExpandoObject();
o.OnlineDetails.Password = client.Element(XKey.onlineDetails)
.Element(XKey.password).Value;
o.OnlineDetails.Roles = client.Element(XKey.onlineDetails)
.Element(XKey.roles)
.Elements(XKey.roleId)
.Select(xroleid => xroleid.Value);
return o;
});
It is true that your second version creates new Func instance repeatedly - however, this just means allocating some small object (closure) and using pointer to a function. I don't think this is a large overhead compared to dynamic lookups that you need to perform in the body of the delegate (to work with dynamic objects).
Alternatively, you could declare a local lambda function like this:
Func<XElement, ExpandoObject> convert = client => {
dynamic o = new ExpandoObject();
o.OnlineDetails = new ExpandoObject();
o.OnlineDetails.Password =
client.Element(XKey.onlineDetails).Element(XKey.password).Value;
o.OnlineDetails.Roles = client.Element(XKey.onlineDetails).
Element(XKey.roles).Elements(XKey.roleId).
Select(xroleid => xroleid.Value);
// More fields TBD.
return o;
}
var qClients =
from client in xdoc.Root.Element(XKey.clients).Elements(XKey.client)
select convert(client);
This way, you can create just a single delegate, but keep the code that does the conversion close to the code that implements the query.
Another option would be to use anonymous types instead - what are the reasons for using ExpandoObject in your scenario? The only limitation of anonymous types would be that you may not be able to access them from other assemblies (they are internal), but working with them using dynamic should be fine...
Your select could look like:
select new { OnlineDetails = new { Password = ..., Roles = ... }}
Finally, you could also use Reflection to convert anonymous type to ExpandoObject, but that would probably be even more inefficient (i.e. very difficult to write efficiently)