I seem to be missing something and extensive use of google didn't help to improve my understanding...
Here is my problem:
I like to create my domain model in a persistence ignorant manner, for example:
I don't want to add virtual if I don't need it otherwise.
I don't like to add a default constructor, because I like my objects to always be fully constructed. Furthermore, the need for a default constructor is problematic in the context of dependency injection.
I don't want to use overly complicated mappings, because my domain model uses interfaces or other constructs not readily supported by the ORM.
One solution to this would be to have separate domain objects and data entities. Retrieval of the constructed domain objects could easily be solved using the repository pattern and building the domain object from the data entity returned by the ORM. Using AutoMapper, this would be trivial and not too much code overhead.
But I have one big problem with this approach: It seems that I can't really support lazy loading without writing code for it myself. Additionally, I would have quite a lot of classes for the same "thing", especially in the extended context of WCF and UI:
Data entity (mapped to the ORM)
Domain model
WCF DTO
View model
So, my question is: What am I missing? How is this problem generally solved?
UPDATE:
The answers so far suggest what I already feared: It looks like I have two options:
Make compromises on the domain model to match the prerequisites of the ORM and thus have a domain model the ORM leaks into
Create a lot of additional code
UPDATE:
In addition to the accepted answer, please see my answer for concrete information on how I solved those problems for me.
I would question that matching the prereqs of an ORM is necessarily "making compromises". However, some of these are fair points from the standpoint of a highly SOLID, loosely-coupled architecture.
An ORM framework exists for one sole reason; to take a domain model implemented by you, and persist it into a similar DB structure, without you having to implement a large number of bug-prone, near-impossible-to-unit-test SQL strings or stored procedures. They also easily implement concepts like lazy-loading; hydrating an object at the last minute before that object is needed, instead of building a large object graph yourself.
If you want stored procs, or have them and need to use them (whether you want to or not), most ORMs are not the right tool for the job. If you have a very complex domain structure such that the ORM cannot map the relationship between a field and its data source, I would seriously question why you are using that domain and that data source. And if you want 100% POCO objects, with no knowledge of the persistence mechanism behind, then you will likely end up doing an end run around most of the power of an ORM, because if the domain doesn't have virtual members or child collections that can be replaced with proxies, then you are forced to eager-load the entire object graph (which may well be impossible if you have a massive interlinked object graph).
While ORMs do require some knowledge in the domain of the persistence mechanism in terms of domain design, an ORM still results in much more SOLID designs, IMO. Without an ORM, these are your options:
Roll your own Repository that contains a method to produce and persist every type of "top-level" object in your domain (a "God Object" anti-pattern)
Create DAOs that each work on a different object type. These types require you to hard-code the get and set between ADO DataReaders and your objects; in the average case a mapping greatly simplifies the process. The DAOs also have to know about each other; to persist an Invoice you need the DAO for the Invoice, which needs a DAO for the InvoiceLine, Customer and GeneralLedger objects as well. And, there must be a common, abstracted transaction control mechanism built into all of this.
Set up an ActiveRecord pattern where objects persist themselves (and put even more knowledge about the persistence mechanism into your domain)
Overall, the second option is the most SOLID, but more often than not it turns into a beast-and-two-thirds to maintain, especially when dealing with a domain containing backreferences and circular references. For instance, for fast retrieval and/or traversal, an InvoiceLineDetail record (perhaps containing shipping notes or tax information) might refer directly to the Invoice as well as the InvoiceLine to which it belongs. That creates a 3-node circular reference that requires either an O(n^2) algorithm to detect that the object has been handled already, or hard-coded logic concerning a "cascade" behavior for the backreference. I've had to implement "graph walkers" before; trust me, you DO NOT WANT to do this if there is ANY other way of doing the job.
So, in conclusion, my opinion is that ORMs are the least of all evils given a sufficiently complex domain. They encapsulate much of what is not SOLID about persistence mechanisms, and reduce knowledge of the domain about its persistence to very high-level implementation details that break down to simple rules ("all domain objects must have all their public members marked virtual").
In short - it is not solved
(here goes additional useless characters to post my awesome answer)
All good points.
I don't have an answer (but the comment got too long when I decided to add something about stored procs) except to say my philosophy seems to be identical to yours and I code or code generate.
Things like partial classes make this a lot easier than it used to be in the early .NET days. But ORMs (as a distinct "thing" as opposed to something that just gets done in getting to and from the database) still require a LOT of compromises and they are, frankly, too leaky of an abstraction for me. And I'm not big on having a lot of dupe classes because my designs tend to have a very long life and change a lot over the years (decades, even).
As far as the database side, stored procs are a necessity in my view. I know that ORMs support them, but the tendency is not to do so by most ORM users and that is a huge negative for me - because they talk about a best practice and then they couple to a table-based design even if it is created from a code-first model. Seems to me they should look at an object datastore if they don't want to use a relational database in a way which utilizes its strengths. I believe in Code AND Database first - i.e. model the database and the object model simultaneously back and forth and then work inwards from both ends. I'm going to lay it out right here:
If you let your developers code ORM against your tables, your app is going to have problems being able to live for years. Tables need to change. More and more people are going to want to knock up against those entities, and now they all are using an ORM generated from tables. And you are going to want to refactor your tables over time. In addition, only stored procedures are going to give you any kind of usable role-based manageability without dealing with every tabl on a per-column GRANT basis - which is super-painful. If you program well in OO, you have to understand the benefits of controlled coupling. That's all stored procedures are - USE THEM so your database has a well-defined interface. Or don't use a relational database if you just want a "dumb" datastore.
Have you looked at the Entity Framework 4.1 Code First? IIRC, the domain objects are pure POCOs.
this what we did on our latest project, and it worked out pretty well
use EF 4.1 with virtual keywords for our business objects and have our own custom implementation of T4 template. Wrapping the ObjectContext behind an interface for repository style dataaccess.
using automapper to convert between Bo To DTO
using autoMapper to convert between ViewModel and DTO.
you would think that viewmodel and Dto and Business objects are same thing, and they might look same, but they have a very clear seperation in terms of concerns.
View Models are more about UI screen, DTO is more about the task you are accomplishing, and Business objects primarily concerned about the domain
There are some comprimises along the way, but if you want EF, then the benfits outweigh things that you give up
Over a year later, I have solved these problems for me now.
Using NHibernate, I am able to map fairly complex Domain Models to reasonable database designs that wouldn't make a DBA cringe.
Sometimes it is needed to create a new implementation of the IUserType interface so that NHibernate can correctly persist a custom type. Thanks to NHibernates extensible nature, that is no big deal.
I found no way to avoid adding virtual to my properties without loosing lazy loading. I still don't particularly like it, especially because of all the warnings from Code Analysis about virtual properties without derived classes overriding them, but out of pragmatism, I can now live with it.
For the default constructor I also found a solution I can live with. I add the constructors I need as public constructors and I add an obsolete protected constructor for NHibernate to use:
[Obsolete("This constructor exists because of NHibernate. Do not use.")]
protected DataExportForeignKey()
{
}
Related
I have read many posts concerning the issue of having several databases and how to design a DAL efficiently in this case. In many cases, the forum suggests to apply the repository pattern, which works fine in most cases.
However, I find myself in a different situation. I have 3 different databases: Oracle, OLE DB and SQLServer. Currently, there exists a unique DAL with many different classes sending SQL queries down to a layer below to be executed in the corresponding database. They way the system works is that two of the databases are only used to read information from them, and the other one is used to either store this same information or read it later on. I have to propose a better design to the current implementation, but it seems as if a common interface for all three databases is not plausible from an architectural point of view.
Is there any design pattern that solves this situation? Should I have three different DALs? Or perhaps it is possible (and advisable) to apply the repository pattern to this problem?
Answers to your question will probably be very subjective. These are some thoughts.
You could apply command-query separation. The query side integrates directly with your data layer, bypassing any business or domain layer, and the returning entities are optimized for read and project from your databases. This layer could also be responsible to merge results from different database calls.
The command side consists of command handlers, using domain or business entities, which are mapped from your R/W database.
By doing this, the interface that you expose will be more clear and business oriented.
I'm not sure that completely abstracting out the data access layer with custom units of work and repositories is really needed: do the advantages outweigh the disadvantages? They rarely do, because you will you ever change a database technology? And if you do, this probably means a rewrite anyway. Also, if you use entity framework code first, you already have unit of work and an abstraction on top of your database; and the flexibility of using LINQ.
Bottom line - try not to over-engineer/over-abstract things; or make things super-generic.
Your core/business code should never be dependent on any contract/interface/class that is placed in the DAL layer of the application.
Accessing data is something the business/core layer of your application needs to be able to do, and this it should be able to do without any dependency of SQL statements and without having any knowledge of the underlying data access technology.
I think you need to remove any "sql" statements from the core part of the application. SQL is vendor dependent and any dependency to a specific database engine needs to be clean out of you core, and moved to the DAL where it belongs. Then you need to create interfaces that resides outside of the DAL(s) which you then create implementation classes for in one or many DAL modules/classes. Your DAL can be dependent of your core, but not the other way around.
I don't see why the repository layer can't be used in this case. When I have a database which I can only read from, I usually let the name of the repository interface indicate this, like ICompanyRepositoryRead.
So my programming background is very self-taught and sporadic. I am working on an MVC4 project and am trying to focus on best practices rather than just functionality.
The general sense of the project is a report generator. So I am trying to understand what exactly Domain Model vs View Model are, and how they related to the models used for CodeFirst Entity Framework. Any tips are appreciated.
From my understanding, let's say my Report object has multiple properties, but for the view I only want a user to be able to edit certain properties, then the ViewModel would be something that maps between the Report object and the user input?
Sounds like you've got the right idea. A ViewModel is the View representation of the domain entity. This can be applied to both data coming in and data going out of the model.
But, the extra layer (and mappings) also increase complexity of the code. You now need a view model class, a mapper class, and a domain entity (EF). So, if you can build what you need without this extra layer, then keep it simple. Domain models and domain modeling should only be used for a business domain that is significantly complex.
Yes your understanding is correct.
View model is data object used by your view. It contains properties necessary either for showing some data to user or collecting data from user. Those properties doesn't necessarily be only data. For example you can have some properties used to control if any field in the input form will be enabled or disabled.
Domain model on the other hand is object used for your logic and persistence. Again it doesn't necessarily contain only persisted properties. There can be other properties computed from persisted properties and there can be also methods working on top of properties.
In some very simple scenarios view model and domain model can be represented by the same object.
This is what I've seen in a few examples, what I've used for the last couple years and feel comfortable with, and was also the pattern already in use by a preexisting MVC team when I came into my most recent job.
Basically entity framework, or whatever ORM your using, will have Entity classes. These are either simple POCO's or something heavier with some ORM's. The goal is for the relationships between entities to closely resemble reality, and as such they are in a way your "Domain models". Either way, you will often find that you're view needs to either flatten properties from child/parent objects, or as you mentioned, only display certain fields.
Often times you will also need additional fields on the view model. For example, the options for a dropdown list, as these aren't part of the entity(only the foreign key that indicates which item is selected is in the entity, but not the list of items from which the user can select).
So unless your view is simple enough to be able to use the #model of your EF entity, often times you may need a ViewModel(VM) class. Some people have a different VM for each view. I personally try to reuse my VMs. Usually a PersonSummaryViewModel which is just a few fields good for things like select lists or indexes where space is limited and I will only display important fields, and a PersonViewModel which are all the fields from the entity, as well as fields for items for dropdown lists(but when used on a readonly page those are simply left null).
Personally I like to name things PersonVM and PersonSummaryVM but others prefer more verbose naming of PersonViewModel. EF will give your entities names like Person, but I've seen other ORM frameworks suffix all of the classes with Entity so you have PersonEntity. I've come to be fond of the Entity suffix personally.
If your database is well designed, it is likely that your entity classes are pretty close to what some would consider your domain model.
We have classes that expose static methods which we call to retrieve data. The controllers have little to no database code in them, and instead all of that are in static methods like PersonModelFactory.GetList(), PersonModelFactory.GetSingle(int id), .Save(PersonVM person) which are responsible for querying the database, and populating the data from the entities into the view models, and then returning a view model. These methods also perform certain validation(beyond what basic things you can do with data annotations on your view models), and other business logic IF it is something that should occur in tandem with whatever database modification is occurring. There's more to the implementation details involving interfaces and generic parameters that are aimed at making these methods very reusable but it is a little complicated for the scope of this post. We've actually successfully reused these classes from both web forms and MVC, so they've proved there re-usability. Some people wouldn't like the fact the DB access, mapping, and business logic/validation occurs in the same layer, but since the DB modification shouldn't occur unless validation passes, we felt it was important for these things to be atomic and mutually dependent.
It is probably more common for people to use the "repository pattern" for database access layer with MVC, and there are even scaffolding for MVC to generate these classes for you. However, these generally won't handle mapping or business logic.
Either way, the main goal is reuse and minimizing the clutter in your controller actions. Before adopting the factor pattern I mentioned, I found my controllers becoming cluttered. I saw opportunities for code to be reused between actions, and thus I was creating private methods in the controller. I really like the factory pattern the team I'm on now uses alot more.
You will definitely find many variations of how people use view models and repositories.
I cannot recall having seen any articles or examples that speak specifically about "domain models" in the context of MVC. IMO domain modelling is part of the requirements gathering process, and then the design of the database/entity framework will reflect the results of those findings. Given limitations of time/resources/complexity you may simplify the domain model. There are frameworks that deal with things like domain languages and what not, I don't think that kind of thing is very common.
Before there were ORMs, there were people doing alot of mapping manually between the database layer(consisting of command objects running SQL), into "business objects" which were often POCOs, basically what you have as EF entities, but sometimes they had some business validation/logic incorporated somehow. Now I don't hear people talk about "business objects" hardly ever because the purpose that layer served has mostly been replaced with EF, and the business logic is either in controller actions or in some other service layer.
Over the years, one thing is certain, what "view model", "business model", "entity", and "domain model" mean to different people will vary.
Not sure if there's a "offical" name, but by DataContext I mean an object which transparently maintains objects' state, providing change tracking, statement-of-work functionality, concurrency and probably many other useful features. (In Entity Framework it's ObjectContext, in NHibernate - ISession).
Eventually I've come to an idea that something like that should be implemented in my application (it uses mongodb as back-end, and mongodb's partial updates are fine when we're able to track a certain property change).
So actually, I've got several questions on this subject
Could anyone formulate requirements to DataContext? - what's your understanding of it's tasks and responsibilities? (The most relevant I've managed to find is Esposito's book, but unfortunately that's at about msdn samples level).
What would you suggest for changes tracking implementation? (In simplest way it's possible to track changes "manually" in entities, but requires coding and mixes dal with business logic, so I mostly interested in "automatic" way, keeping entities more poco).
Is there way to utilize some existing solution? (I hoped nhibernate infrastructure would allow plugging-in custom module to work with mongo behind the scene, but not sure if it allows working with non-sql dbs at all).
The DataContext (ObjectContext or DbContext in EF) is nothing else than an implementation of the Unit of Work (UoW)/Repository pattern.
I suggest you Fowler's book on Patterns of Enterprise Application Architecture in which he outlines the implementation of several persistency patterns. That might be a help in implementing your own solution.
A DataContext basically needs to fullfil the job of a UoW. It needs to handle the reading and management of objects that are involved in a given lifecycle (i.e. HTTP request), s.t. there are no two objects in memory that represent the same record on the DB. Moreover it needs to provide some change tracking for performing partial updates to the DB (as you already mentioned).
To what regards change tracking, I fully agree that polluting properties with change events etc is bad. One of the recent templates introduced in EF4.1 uses Proxies to handle that and to give the possibility to have plain POCOs.
Answer to quetion 2: To make POCO classes work, you will need to generate code at run-time, possibly using System.Reflection.
If you analyse EntityFramework, you will see that it requires virtual properties to do change-tracking... that is because it needs to create a generated class at run-time, that overrides each property, and then adds code to tell the DataContext when someone changes that property.
EntityFramework also generates code to initialize collections, so that when someone try to do operations like Add and Remove, the collection object itself knows what to do.
POCO = Plain Old CLR (or better: Class) Object
DTO = Data Transfer Object
In this post there is a difference, but frankly most of the blogs I read describe POCO in the way DTO is defined: DTOs are simple data containers used for moving data between the layers of an application.
Are POCO and DTO the same thing?
A POCO follows the rules of OOP. It should (but doesn't have to) have state and behavior. POCO comes from POJO, coined by Martin Fowler [anecdote here]. He used the term POJO as a way to make it more sexy to reject the framework heavy EJB implementations. POCO should be used in the same context in .Net. Don't let frameworks dictate your object's design.
A DTO's only purpose is to transfer state, and should have no behavior. See Martin Fowler's explanation of a DTO for an example of the use of this pattern.
Here's the difference: POCO describes an approach to programming (good old fashioned object oriented programming), where DTO is a pattern that is used to "transfer data" using objects.
While you can treat POCOs like DTOs, you run the risk of creating an anemic domain model if you do so. Additionally, there's a mismatch in structure, since DTOs should be designed to transfer data, not to represent the true structure of the business domain. The result of this is that DTOs tend to be more flat than your actual domain.
In a domain of any reasonable complexity, you're almost always better off creating separate domain POCOs and translating them to DTOs. DDD (domain driven design) defines the anti-corruption layer (another link here, but best thing to do is buy the book), which is a good structure that makes the segregation clear.
It's probably redundant for me to contribute since I already stated my position in my blog article, but the final paragraph of that article kind of sums things up:
So, in conclusion, learn to love the POCO, and make sure you don’t spread any misinformation about it being the same thing as a DTO. DTOs are simple data containers used for moving data between the layers of an application. POCOs are full fledged business objects with the one requirement that they are Persistence Ignorant (no get or save methods). Lastly, if you haven’t checked out Jimmy Nilsson’s book yet, pick it up from your local university stacks. It has examples in C# and it’s a great read.
BTW, Patrick I read the POCO as a Lifestyle article, and I completely agree, that is a fantastic article. It's actually a section from the Jimmy Nilsson book that I recommended. I had no idea that it was available online. His book really is the best source of information I've found on POCO / DTO / Repository / and other DDD development practices.
POCO is simply an object that does not take a dependency on an external framework. It is PLAIN.
Whether a POCO has behaviour or not it's immaterial.
A DTO may be POCO as may a domain object (which would typically be rich in behaviour).
Typically DTOs are more likely to take dependencies on external frameworks (eg. attributes) for serialisation purposes as typically they exit at the boundary of a system.
In typical Onion style architectures (often used within a broadly DDD approach) the domain layer is placed at the centre and so its objects should not, at this point, have dependencies outside of that layer.
I wrote an article for that topic: DTO vs Value Object vs POCO.
In short:
DTO != Value Object
DTO ⊂ POCO
Value Object ⊂ POCO
I think a DTO can be a POCO. DTO is more about the usage of the object while POCO is more of the style of the object (decoupled from architectural concepts).
One example where a POCO is something different than DTO is when you're talking about POCO's inside your domain model/business logic model, which is a nice OO representation of your problem domain. You could use the POCO's throughout the whole application, but this could have some undesirable side effect such a knowledge leaks. DTO's are for instance used from the Service Layer which the UI communicates with, the DTO's are flat representation of the data, and are only used for providing the UI with data, and communicating changes back to the service layer. The service layer is in charge of mapping the DTO's both ways to the POCO domain objects.
Update Martin Fowler said that this approach is a heavy road to take, and should only be taken if there is a significant mismatch between the domain layer and the user interface.
TL;DR:
A DTO describes the pattern of state transfer. A POCO doesn't describe much of anything except that there is nothing special about it. It's another way of saying "object" in OOP. It comes from POJO (Java), coined by Martin Fowler who literally just describes it as a fancier name for 'object' because 'object' isn't very sexy and people were avoiding it as such.
Expanding...
Okay to explain this in a far more high-brow way that I ever thought would be needed, beginning with your original question about DTOs:
A DTO is an object pattern used to transfer state between layers of concern. They can have behavior (i.e. can technically be a poco) so long as that behavior doesn't mutate the state. For example, it may have a method that serializes itself. For it to be a proper DTO, it needs to be a simple property bag; it needs to be clear that this object is not a strong model, it has no implied semantic meaning, and it doesn't enforce any form of business rule or invariant. It literally only exists to move data around.
A POCO is a plain object, but what is meant by 'plain' is that it is not special and does not have any specific requirements or conventions. It just means it's a CLR object with no implied pattern to it. A generic term. I've also heard it extended to describe the fact that it also isn't made to work with some other framework. So if your POCO has a bunch of EF decorations all over it's properties, for example, then it I'd argue that it isn't a simple POCO and that it's more in the realm of DAO, which I would describe as a combination of DTO and additional database concerns (e.g. mapping, etc.). POCOs are free and unencumbered like the objects you learn to create in school
Here some examples of different kinds of object patterns to compare:
View Model: used to model data for a view. Usually has data annotations to assist binding and validation for particular view (i.e. generally NOT a shared object), or in this day and age, a particular view component (e.g. React). In MVVM, it also acts as a controller. It's more than a DTO; it's not transferring state, it's presenting it or more specifically, forming that state in a way that is useful to a UI.
Value Object: used to represent values, should be immutable
Aggregate Root: used to manage state and invariants. should not allow references to internal entities other than by ID
Handlers: used to respond to an event/message.
Attributes: used as decorations to deal with cross-cutting concerns. May only be allowed to be used on certain objects levels (e.g. property but not class, method but not property, etc.)
Service: used to perform complex tasks. Typically some form of facade.
Controller: used to control flow of requests and responses. Typically restricted to a particular protocol or acts as some sort of mediator; it has a particular responsibility.
Factory: used to configure and/or assemble complex objects for use when a constructor isn't good enough. Also used to make decisions on which objects need to be created at runtime.
Repository/DAO: used to access data. Typically exposes CRUD operations or is an object that represents the database schema; may be marked up with implementation specific attributes. In fact, one of these schema DAO objects is actually another kind of DTO...
API Contracts: Likely to be marked up with serialization attributes. Typically needs to have public getters and setters and should be lightweight (not an overly complex graph); methods unrelated to serialization are not typical and discouraged.
These can be seen as just objects, but notice that most of them are generally tied to a pattern or have implied restrictions. So you could call them "objects" or you could be more specific about its intent and call it by what it is. This is also why we have design patterns; to describe complex concepts in a few words. DTO is a pattern. Aggregate root is a pattern, View Model is a pattern (e.g. MVC & MVVM).
A POCO doesn't describe a pattern. It is just a different way of referring to classes/objects in OOP which could be anything. Think of it as an abstract concept; they can be referring to anything. IMO, there's a one-way relationship though because once an object reaches the point where it can only serve one purpose cleanly, it is no longer a POCO. For example, once you mark up your class with decorations to make it work with some framework (i.e. 'instrumenting' it), it is no longer a POCO. Therefore I think there are some logical relationships like:
A DTO is a POCO (until it is instrumented)
A POCO might not be a DTO
A View Model is a POCO (until it is instrumented)
A POCO might not be View Model
The point in making a distinction between the two is about keeping patterns clear and consistent in effort to not cross concerns and lead to tight coupling. For example if you have a business object that has methods to mutate state, but is also decorated to hell with EF decorations for saving to SQL Server AND JsonProperty so that it can be sent back over an API endpoint. That object would be intolerant to change, and would likely be littered with variants of properties (e.g. UserId, UserPk, UserKey, UserGuid, where some of them are marked up to not be saved to the DB and others marked up to not be serialized to JSON at the API endpoint).
So if you were to tell me something was a DTO, then I'd probably make sure it was never used for anything other than moving state around. If you told me something was a view model, then I'd probably make sure it wasn't getting saved to a database, and I'd know that it's ok to put 'hacky' things in there to make sure the data is usable by a UI. If you told me something was a Domain Model, then I'd probably make sure it had no dependencies on anything outside of the domain and certainly no dependencies on any technical implementation details (databases, services etc.), only abstractions. But if you told me something was a POCO, you wouldn't really be telling me much at all other than it is not and should not be instrumented.
History
Paraphrased from Fowler's explanation: In a world where objects were fancy (e.g. followed a particular pattern, had instrumentation etc.), it somehow encouraged people to avoid using not-fancy objects to capture business logic. So they gave it a fancy name POJO. If you want an example, the one he refers to is an "Entity Bean" which is one of those kinds of objects that have very specific conventions and requirements, etc.. If you don't know what that is --> Java Beans.
In contrast, a POJO/POCO is just the regular ole object that you'd learn out to create in school.
A primary use case for a DTO is in returning data from a web service. In this instance, POCO and DTO are equivalent. Any behavior in the POCO would be removed when it is returned from a web service, so it doesn't really matter whether or not it has behavior.
DTO objects are used to deserialize data into objects from different sources. Those objects are NOT your Model (POCO) objects. You need to transform those objects into your Model (POCO) objects. The transformation is mostly a copy operation. You can fill those POCO objects directly from the source if its an internal source, but its not adviceable if its an external source. External sources have API's with descriptions of the Schema they use. Its much easier then to load the request data in an DTO and after that transform those in your POCO's. Yes its an extra step, but with a reason. The rule is to load the data from your source in an object. It can be JSON, XML whatever. When loaded then transform that data in what you need in your model. So most of times the DTO is an object image of the external source. Sometimes you even get the Schema's of the source providers then you can deserialize even easier, XML works like that with XSD's.
here is the general rule: DTO==evil and indicator of over-engineered software. POCO==good. 'enterprise' patterns have destroyed the brains of a lot of people in the Java EE world. please don't repeat the mistake in .NET land.
Don't even call them DTOs. They're called Models....Period. Models never have behavior. I don't know who came up with this dumb term DTO but it must be a .NET thing is all I can figure. Think of view models in MVC, same dam** thing, models are used to transfer state between layers server side or over the wire period, they are all models. Properties with data. These are models you pass ove the wire. Models, Models Models. That's it.
I wish the stupid term DTO would go away from our vocabulary.
For a large project, would it make sense to have one datacontext which maps out your database, which you can interact with from your classes?
Or would it make more sense to split this up into small datacontexts which are focused on the specific tasks within the database that will be required.
I'm curious as to the performance. It's my understanding that the datacontext itself is a very lightweight object, which only initializes its internal collections as they're required etc. Therfore dealing with a datacontext with many defintions but only two tables of data should be as fast as dealing with a special datacontext with only those two tables in it.
I also think you would benefit at the JIT time, as the first class to do data access will compile your dc which is now available to all classes.
I'm assuming you're asking about design versus runtime pattern. I general I'd say no:
While it may be possible to partition your database into multiple data contexts, then that would be desirable if and only if there was zero overlap between the two contexts.
Overlap is Bad
e.g. you have a WebsiteContext and an AdminContext. The WebsiteContext is for displaying Product and fulfilling Orders. A WebsiteUser is attached to an Order. The AdminContext is for your Staff members to process refunds for cancelled Orders, which also reference WebsiteUser. The AdminContext also needs to reset passwords and update other details for the WebsiteUser.
You're thinking of doing this because you don't want the website to process or even know about Returns
WebsiteContext
Product -- Order -- WebsiteUser
AdminContext
Staff -- Returns -- Order -- WebsiteUser
In the above, we can see we're duplicating many objects in the different Data Contexts. This smells bad, and it really indicates that artificially dividing the database into different data contexts is a the wrong decision. Do you have >2 databases after all, or just the one? The duplication violates the DRY principle (Dont Repeat Yourself) because WebsiteContext.WebsiteUser is not the same as AdminContext.WebsiteUser and in all likelihood the code is going to be messy when something needs to care which one they're referencing.
The Linq Data Context is just an OR mapper, and needs to be treated as a fancy black box that makes writing some of the data access code easier. Some linq demos make it look like you no longer need the other layers, but a program of any complexity still benefits from a layered design.
You're probably better off treating the Linq objects as just objects for easily transferring data and create a Domain layer that hides them as an implementation detail. Have a read of DDD - Domain Driven Design.
On their own, just using the Linq objects from the UI most resembles the Transaction Script pattern. In such a case you'd still benefit from having a logic layer that takes care of the details.
While you may not want the responsibility of a context to be so broad, the data context is just a representation of the database. It's not a security mechanism, and it can't prevent you from corrupting the data.
From a "repository pattern" angle, there is something to be said for having separate aggregates and minimizing the navigation properties between aggregates. I'm not 100% sure what that something is though... at the moment I'm considering using a moderately-sized dbml, with multiple repositories using it (the UI doesn't use the datacontexts directly - only the repository classes), with the navigation properties marked internal so the DAL can use them... Maybe...