I'm considering using PostSharp for entity-to-DTO and DTO-to-entity mapper. To do that task manualy for about a 100 entities would be a maintenence nightmare. I've looked at AutoMapper on codeplex, but i think the overhead might be a serious problem in my case, besides i feel that PostSharp could give me some extra control over the mapping convention. If anyone can share any experiences with this king of problems, that would be great.
The direction i'm think in is something like this (please somebody tell me if this is not possible):
The aspect that i am planing to stick to a class would fill the next two methods with content:
EntityType EntityToDTO(DTOType DTO) {}
DTOType DTOToEntity(EntityType Entity) {}
The first method would return entity based on DTO, the second one would do the oposite. Inside the aspect i'm planing to loop through each property, create new target and asign the value of a property to the counterpart from target object. Is this possible to do at compiletime witout any runtime overhead?
If your DTOs field names match your entity field names, then I'd use Duck Typing
http://www.deftflux.net/blog/page/Duck-Typing-Project.aspx
http://haacked.com/archive/2007/08/19/why-duck-typing-matters-to-c-developers.aspx
Your code would work like this
UserDTO user = DuckTyping.Cast<UserDTO>(userEntity);
Basically, the duck typing library will be mapping over the fields by matching the names. They use dynamically generated IL to archive this.
If that has the potential of being too slow, I'd probably try to get CodeSmith to generate the methods for me.
If it helps, there is a project called PostSharp4ET that basically implements support for POCO objects to Entity Framework 1. See http://www.codeplex.com/efcontrib.
Note that PostSharp is not very good at generating new code. It is good at mixing new code with existing one. If you need to generate code, I would recommend writing a C# code generator based on reflection, and compile the resulting code. Or use a tool like CodeSmith, as mentioned previously.
Related
I need to create a web service and generate the corresponding WSDL file.
I need to provide a list of fields related to a customer, such the name, the address and so on.
The problem is I need to keep them in the body of the WSDL without generating a complex type, but I would like to wrap all these fields in the Customer class.
Is there a way not to generate the complex type from a class, and tell to just consider its variables? Googling around I always found the opposite question!
Thanks in advance.
EDIT: To explain it a little bit better, my WSDL should have a similar snippet:
<pos:NAME>?</pos:NAME>
<pos:SURNAME>?</pos:SURNAME>
<pos:ADDRESS>?</pos:ADDRESS>
<pos:OTHER_DATA>?</pos:OTHER_DATA>
<pos:OTHER_DATA2>?</pos:OTHER_DATA2>
<pos:OTHER_DATA3>?</pos:OTHER_DATA3>
I would like to create a "Customer" class in my code for better code management, without the risk of generating something like:
<pos:CUSTOMER>
<pos:NAME>?</pos:NAME>
<pos:SURNAME>?</pos:SURNAME>
<pos:ADDRESS>?</pos:ADDRESS>
</pos_CUSTOMER>
<pos:OTHER_DATA>?</pos:OTHER_DATA>
<pos:OTHER_DATA2>?</pos:OTHER_DATA2>
<pos:OTHER_DATA3>?</pos:OTHER_DATA3>
I have a regular C# class called "vehicle" with properties like Name, NumberPlate, MaxSpeed, etc.
All the data for the class is stored in a SQLite Database where I have a Table "Car" and "Boat". The tables colums have the same names as the class properties (however, there are more columns than class properties - vehicle is a more generic abstraction). At the moment, I have to assign the result of the query individually one by one like this:
while (await statement.StepAsync())
{
myVehicle.Name = statement.Columns["Name"];
//[...]
myVehicle.MaxSpeed = decimal.TryParse(statement.Columns["MaxSpeed"]);
}
Additionally, I have to check if some columns exist ("Car" and "Boat" have a different set of columns) which is more code than I'd like it to be.
I read about EntityFramework to map my db table to my class - but that seems overkill. My requirement is to map properties and columns that have the same name and ignore everything else.
Is there a "easy" (dev time, lines of code) way to map my table columns to my class?
Thanks for reading!
The restrictions in phone 8 mean that a lot of the standard answers to this ("just use {some ORM / micro-ORM}") won't apply, since they don't work on phone 8. You can probably use reflection for a lot of this, but: reflection can be (relatively) slow, so it depends on how much data you will be processing. If it is occasional and light: fine, reflect away.
Runtime meta-programming (the tricks used by libraries like "dapper" in full .NET to make these things really fast) is not available on restricted runtimes, so if you want to avoid lots of boiler-plate that leaves build-time meta-programming. At the simplest, I wonder if you could use something like T4 to automate creating these methods for you as C#. There are also ways to use the reflection-emit API to construct assemblies (at build-time) for phone 8, but that is a pretty hard-core route.
My thoughts:
if the amount of types here isn't huge, just write the code
if you have a lot of types, or you just feel like it, consider a build-time code-generation meta-programming step; you might even think "hmm, is this something I could make available to the community?"
of course, the first thing to do is to check that such a thing doesn't already exist
There is a little helper which might fit your case. Basically, it will take a dictionary and try it's best to populate a objects properties using reflection. I didn't try it by myself though.
You'd simply do something like:
while (await statement.StepAsync())
{
myVehicle = DictionaryToObject<Car>(statement.Columns);
}
It might need some further work to get it running but maybe a good start.
How would you do this (pseudo code): product1.Orders.AddRange(product2.Orders);
However, the function "AddRange" does not exist, so how would you copy all items in the EntityCollection "Orders" from product2 to product1?
Should be simple, but it is not...
The problem is deeper than you think.
Your foreach attempt fails, because when you call product1.Orders.Add, the entity gets removed from product2.Orders, thus rendering the existing enumerator invalid, which causes the exception you see.
So why does entity get removed from produc2? Well, seems quite simple: because Order can only belong to one product at a time. The Entity Framework takes care of data integrity by enforcing rules like this.
If I understand correctly, your aim here is to actually copy the orders from one product to another, am I correct?
If so, then you have to explicitly create a copy of each order inside your foreach loop, and then add that copy to product1.
For some reason that is rather obscure to me, there is no automated way to create a copy of an entity. Therefore, you pretty much have to manually copy all Order's properties, one by one. You can make the code look somewhat more neat by incorporating this logic into the Order class itself - create a method named Clone() that would copy all properties. Be sure, though, not to copy the "owner product reference" property, because your whole point is to give it another owner product, isn't it?
Anyway, do not hesitate to ask more questions if something is unclear. And good luck.
Fyodor
Based on the previous two answers, I came up with the following working solution:
public static void AddRange<T>(this EntityCollection<T> destinationEntityCollection,
EntityCollection<T> sourceEntityCollection) where T : class
{
var array = new T[sourceEntityCollection.Count()];
sourceEntityCollection.CopyTo(array,0);
foreach (var entity in array)
{
destinationEntityCollection.Add(entity);
}
}
Yes, the usual collection related functions are not there.
But,
1. Did you check CopyTo method?
2. Do you find any problem with using the iterator? You know, GetEnumerator, go through the collection and copy the entities?
The above two can solve your problems. But, I'm sure in .NET 3.0+ there would be compact solutions.
My answers are related to .NET 2.0
i´m trying to query a DataTable object without specifying the fields, like this :
var linqdata = from ItemA in ItemData.AsEnumerable()
select ItemA
but the returning type is
System.Data.EnumerableRowCollection<System.Data.DataRow>
and I need the following returning type
System.Data.EnumerableRowCollection<<object,object>>
(like the standard anonymous type)
Any idea?
Thanks
If I understand you correctly, you'd like to get a collection of objects that you don't need to define in your code but that are usable in a strongly typed fashion. Sadly, no you can't.
An anonymous type seems like some kind of variant or dynamic object, but it is in fact a strongly typed class that is defined at compile time. .NET defines the type for you automatically behind the scenes. In order for .net to be able to do this, it has to have some clue from the code with which to infer the type definition. It has to have something like:
from ItemA in ItemData.AsEnumerable()
select ItemA.Item("Name"), ItemA.Item("Email")
so it knows what members to define. There's no way to get around it, the information has to logically be there for the anonymous type to be defined.
Depending on why exactly your are trying to do this, there are some options.
If you want intellisense while still encapsulating your data access, you can return xml instead of a datatable from your encapsulated data access class. (You can convert data tables to xml very easily. You'll want to use the new System.Xml.Linq classes like the XElement. They're great!) Then you can use VS2008's ability to create an xsd schema from xml. Then use/import that schema at the top of your code page, and you have intellisense.
If you have to have an object an with properties for your data, but don't want to define a class/structure for them, you'll love the new dynamic objects coming in C#4.0/VB10. You have object properties based on what the sql returns, but you won't have intellisense. There is also a performance cost to this, but (a) that might not matter for your situation and (b) it actually is not so bad in some situations.
If you're just trying to avoid making a lot of classes, consider defining structs/structures on the same code file, beneath your class definition. When you add more columns to your result set, it's easy to adjust a struct with more public fields.
In short you can have any two of the following three: (a) dynamic, (b) strontly-typed objects, (3) intellisense. But not all three.
There is one way to accomplish what you want, but it required knowledge of dynamic linq. You would build the query during run-time and then use it. I am no expert and have never really played around with it, but here is a link to Scott Guthrie's blog about it - Dynamic Linq. Hope that helps.
Wade
What have you done to remove (Helpers/extension methods) string literal in code?
e.g. I have nhibernate search criteria code like this all over the place.
Expression.Eq("Status", LoginStatus.LoggedIn),
“Status” being the property of an entity object used as a string in the case.
Update: Primary reason in this case is to enable refactoring. If I write a helper method which reflects the object and gets the value, will make the above expression strongly typed.
This is what "Resources" and "Settings" is for. You can find this by right clicking your project in Visual Studio and clicking "Properties", then going to the "Resources" or "Settings" tab.
For pre-built resources that won't change often, use resources. For things you want to be configurable use Settings instead because it will auto-generate blocks of configuration for your App.config. You will still need to manually copy and paste these values if you do not want to use the defaults.
The nice thing about both is that VS will build a nice static class with properties you can use throughout your code. VS will maintain the class and resources for you dynamically as long as you continue to use the wizard.
I'll usually declare them as constants, or, if I have groups of related strings, I'll create an enum instead.
Either way, at least they have a descriptive name attached to them (instead of using "magic strings"), and their use will always be consistent.
In the past, I've used CodeRush (or your favourite refactoring tool) to convert to a const string in the class, and then moved said const strings to be public members of the entity class to which they apply.
The real answer here, if you're looking to get your code less brittle in the face of refactoring is to get out of the strings business, and use Linq 4/to NHibernate, but you'd have to research whether it's completeness is sufficeint for your purposes.
Realized that I could do this the Expression trees way. Using Code as data!
Something like this
protected IList<T> _FindByProperty<TResult>(Expression<Func<T, TResult>> expression, TResult value)
{
return _FindByProperty((expression.Body as MemberExpression).Member.Name, value);
}
IList<User> costCenters = _FindByProperty( user=> user.Name, "name");
Credits: http://suryagaddipati.wordpress.com/2009/03/14/code-as-data-in-c-taking-advantage-of-expression-trees/
This is related to a lot questions in the expression-trees tag.
I use a similar approach as Cherian. I got my idea from the FluentNhibernate's ReflectionHelper.
The principle is to use expression trees and then you could just put in a x => x.Status expression. The method would return the property name as string.
In fact, you could also just use FluentNHibernate? However, I don't know if their querying model is evenly extensive as their mapping interfaces...