I have a fairly large application, where my data access strategy has always been quite old school:
I have 4 Stored Procedures per Table: TableName_Select, TableName_Insert, TableName_Update, TableName_Delete.
I have a MsSql#DOMAIN#Service class for each logical domain of my application. In that class I have corresponding method to Select, Insert, Update and Delete something in the database.
I want to maintain my own Model classes in a seperate class library project, along with service contracts for WCF services. That enables me to reference only the naked Models, Service Contracts and WCF Service Clients from e.g. a web app or a windows app. (I don't use the auto-generated WCF Service Clients either)
Can I use my own Model classes along with Linq-to-SQL - or do I have to use the autogenerated Models from Linq-to-SQL and then map them over to my own Models in my data access layer before returning them back through the WCF service?
EF Code First FTW!
You don't have to use the auto-generated types with a Linq To Sql data context, but by default the types that you use need to have all the attribute annotations that you'll see on them.
However, Linq to Sql also supports custom mapping (the default being to use the Attributes), where types are mapped to tables and their properties mapped to columns using a MappingSource which is provided to the DataContext on construction.
L2S comes with two - the AttributeMappingSource (used implicitly) and the XMLMappingSource. It's possible with the second of these that you can hand-crank a Linq To Sql DataContext that exposes EntitySets of your own types.
You could even write your own MappingSource - but I think the XML one probably covers most needs.
We have done something similar in our applications. We wrote our own code generator to generate our L2S classes and also what we call our "application" entities. These are much more lightweight than the L2S classes. They are used at the application level to pass data back and forth to our back-end. Each L2S entity class has a built in application entity equivalent where automatic mapping occurs. What I mean is that whenever a L2S entity has data stored to its properties, the values are automatically copied to the respective application entity property. We then have a method on each L2S entity that allows us to retrieve the associated application entity.
So, the short answer is yes, you can use your own classes in conjunction with the L2S entities.
Related
I have taken a step back on two of the approaches in my project (WCF REST Service).
Started with WCFDataServices since it support full OData service stack, but due to more validation requirements on CRUD operations, switched to 'WCF Service' with EF.
And now thinking to step back to use Self-tracking entities to exposing entities to client, as many articles says STE is no more supported by Microsoft and preferred to use OData.(but again WCFDataService not suitable for me).
Please suggest what is the best design here to expose my entities over client.
Alternatively, I may have to write custom classes (Data Contracts) of Entity Model. But, this increases code (for conversion of objects between Custom and Entity) and decreases maintainability.
Please suggest is there any best approach to expose my entities. Your suggestions are valuable and most appreciated.
Fowlers first law of distributed object design states, "don't distribute your objects". This just means give them a copy and not the actual entity itself. If you were to create mirror copies of your entities in your data contract namespace, you retain much more flexibility, should your database schema need changing. If your data contract is initially identical to your entity, a tool such as AutoMapper will eliminate all the conversion code you need to write. Once configured, to convert your entity to your data contract becomes a 1 liner:
Mapper.Map<CustomerDto>(customer);
This takes your customer entity and gives you back a new customer dto. It's all convention based and works by matching up property names. Even if the data contract isn't entirely identical to the entity, you only have to prompt AutoMapper for those properties it can't figure out for itself.
I have been using EF since it first came out. Used to hand build POCOs in 3.5 and was glad to see Self Tracked Entities(STE) in EF4.0.
I have use STEs in a couple of very large projects(500+ entities, some with multiple models). In these projects I use a generic Repository and a generic Unit of Work to persist the entities i.e. 2 small generic classes no mapping. By electing a core entity as the "aggregrate root", other entities are added and updated on the client side and the core entity graph containing these changes is sent to the WCF service and used in the Logic Layer which creates the Repository<[core entity]> and uses the UnitOfWork<[core entity]>.Save(Repository<[core entity]>) to persist the STEs and their children to the database.
Now Microsoft is recommending that we not use STEs. See this article
So my question is, What is(are) the patterns that are now recommended by Microsoft for applications that are persisting client changes to WCF Services that use EF?
I created a EF5 Model and examined the generated code. The there are no attributes for a WCF Service i.e. DataContract, DataMember etc
EF4 had a "ADO.NET DbContext Generator with WCF Support" template, but there isn't a EF5 equivalent.
One site suggested I should use a partial class file and decorate the same properties in that file with these attributes. But unless .net 4.5 has introduced partial properties, I cannot see how that can be done.
Another blog suggested using DTO and Automapper, which means more mapping which is error prone; especially when entity fields change type.
So now that DBContext generated code classes are not Service enabled, does this mean that we need to write another set of classes (POCOs) that:
needs to be mapped FROM the DBContext generated code classes after querying the database.
holds the data state for the WCF Service client(s)
is updatable by that client(s)
is mapped by the client(s)
has the ability to hold changed state so this can be sent back to the WCF Service
needs to be mapped TO the DBContext generated code classes for persistence
It seems we just took a great leap backwards to EF3.
If you code both client and service that runs on your hardware, you don't need to be concerned about data structures at the client as they belong to you.
If you also need to expose some of your service methods to non.NET clients you should do the 5 points above for those services anyway and use DTOs and Automapper in those occasions.These should be in a different WCF Service but implemented against the same Logic Layer, after mapping.
But how many of these type of non.NET client services are be created in the day to day building of web applications in most software teams?
This latest recommendation is confusing as it has not been explained as to WHY STEs are ALWAYS ill-conceived and what now, are the recommended patterns to be used for persisting client changes to WCF Services that use EF.
Can anybody inform me where I can find a good resource that solves this architectural design issue?
P.S.
Please don't recommend WCF Data Services or WCF RIA as we need a lot of control over how your data is retrieved and saved by clients.
Please don't recommend Code First as we use Database First as we want to have and need to control the structure of that database and not have to generated for us.
Ok so i thought the same thing when I first read this article, it seems a bit weird to deprecate a whole branch of EF like this and the intention wasn't terribly well communicated (IMO). I think a couple of things are important here:
STEs as referred to in this article refer to object context based self tracking entities (which act a little like autonomous contexts)
ObjectContext is generally being moved away from in favor of the cleaner DbContext structure (this is for both DB first and Code First)
STEs != DB first generation, you can still use an EDMX model in EF and this isn't likely to change.
When i originally saw this article I mistook STEs for POCO Proxy entities which are still available and AFAIK there are no plans to deprecate. (these achieve a similar technical solution to the problem of change detection but with a nicer interface. Check out this article for the differences EF4: Difference between POCO , Self Tracking Entities , POCO Proxies
So what does this all mean
Basically STEs in terms of the old implementation of a change tracker are being deprecated in favor of the newer forms of change tracking (Snapshot or POCO Proxies). This means that if snapshot tracking doesn't suit you you should look into POCO Proxies which are similar to the old STEs.
You can still use all previous techniques for context generation (DB First, Model First, Code First, and DB-> Code)
Well, I am creating a WCF service, that have a large number of classes to communicate with the client, and this classes have also many properties.
Mainly, this classes are the POCO classes that is created with the code generator from the edmx, and I have the .tt file.
To can use this classes and properties, I have to use the DataContract and DataMember, so in each classes I have to set the DataContract and in each property of the each class the DataMemeber. So this a big work, so if I need to do some modify to the data base, I must generate again the tt file and then repeat the work.
Is there any way to do this automatically? I am using .NET 4.0 and EF 4.1.
The whole point of the .tt file being added to your project is so that you can modify the template to suit your needs. All you need to do is change the template so that it adds [DataContract] to the entity class definition and [DataMember] to the entity property definitions.
From there, any time the DB is changed you simple use the "Update model from database" feature and your entities will automatically have their code regenerated using the existing template.
All that said, I'm going to recommend you do not expose your DB entities, POCO or not, directly from your service layer. You should really be designing with domain separation and using messaging and CQRS type patterns at the service level. Then you just have some simple mapping methods that translate the data between those messages/commands to your entities.
There is Entity Framework Provider with WCF data services, might be it can help you.
Using Entity Framework 4.1 what is the best way to map an auto generated entity framework entity to an object suitable for Data Transfer?
What i'm working with looks like this:
WPF Application -> WCF Service -> Entity Framework (DAL) -> Database
The WPF application could be swapped out to an ASP.NET website at some point in addition to the WPF Application. Hence the use of a WCF service.
The WCF Service, Database and Entity Framework code will all sit on the same physical tier.
In previous versions of Entity Framework (Before 4.0) I believe you had to write your own mapping code for your classes. Is there a better way to do this now?
Also an additional question is would it be bad practice to include methods on the DTO's that performs business logic? Where would be the best place to apply business logic in this case?
The best way to map from EF entities to DTOs is to project. My example linked there uses view models rather than DTOs, but the idea is the same.
With most ORMs, EF included, there is a cost to materializing entities which you don't need to pay if you just need a DTO. The cost includes:
Fixup -- when two objects reference the same related object, make sure they point to the same instance.
Tracking -- overhead for tracking the instance in a context.
Unnecessary columns -- you might not need all properties for your DTOs.
Aggregates -- functions like .Count() are far more efficient in SQL than in object space.
If you use a L2E projection, you don't incur any of this cost. If you follow the common advice to use the AutoMapper hammer for every problem which looks like a nail, you pay all of it.
I do agree with #sternr about not putting methods on entities / DTOs. For a more detailed examination of this idea, read "At the Boundaries, Applications are Not Object-Oriented."
Use AutoMapper to map between simple DTO's and EF entities
[EDIT:] for your other questions:
For the mapping: you could either use the built in edmx designer which allows you to use an existing DB schema to generate your model entities, or the other way around (define your entities, and let EF create your DDL).
Newer versions (as of 4.1) you could simply code your entities and add DataAnnotations on the associated properties and EF will do the magic mapping (here's a good sample)
As for adding logic to DTO's, well DTO's by their definition are a data contact - the consumer will probably create it's own implementation of them (be them by the automatic proxy or other manual wrappers), so placing logic in them kinda makes no sense.
I have a WCF that uses a ADO.NET Entity Data Model to access SQL Server.
To insert a new row in a table with seven columns I'm using a WCF method.
I think send seven parameters it's too much, so I can use a struct or table's entity object.
What do you think? Do you recommend me to expose an entity object through WCF? Or I need to use a struct to avoid do that.
It depends on size / complexity of your application. Exposing entity is possible but it can cause some serialization problems when transporting whole object graph (entity with its relation). These problems are usually solved by marking entities with DataContract and DataMember attributes (used by default if you use EFv1 or default entity generation in EFv4 = no T4 templates).
The second approach you described is recommended if you want to follow clean architecture and good separation of concerns but it will make your application more complex (another layer of objects, conversions, etc.). Structures or classes created for data transportation are generally called DTOs (Data Transfer Objects).
Data Transfer Objects allow you transferring only necessary subset of data required for entity. If you for example have some infrastructural properties in the entity (like CreatedAt, CreatedBy) you will not want client to set these properties because it is responsibility of the service to set them. Because of that there is no need to allow client passing them. By not exposing these properties in the DTO you will make this clear.
My experience of using entities as Data Contracts is that you continually run into all kinds of hassle. Maintaining DTOs is not ideal, but gives you very fine grained control including the ability to change your DB schema without changing your contracts, and also control over the fields exposed by your service.
Automapper can really help you: http://automapper.codeplex.com/