Here is my opinion: When working with any non-sober application. Using your linq2Sql objects as your domain model is a really bad idea. I see linq2Sql as ORM and nothing else. Databases (which linq2Sql has a direct correspondence to) are data normalization. Classes (in the sense of OOAD) are normalization of behavior (not data).
[these class objects are mostly mirror images] ...
I came across this when creating applications using linq2Sql. It will be realistic .... most areas of business applications are renowned CRUD applications. Therefore, it is possible that a large percentage of your applications will correspond to database tables. I did not want to contact directly with the DTOs that were generated, but at the same time I did not want duplicate classes to clog in my application.
So here is my solution:
I "programmed to interface".
Suppose I have PersonDto (Dto standing for a data transfer object) with the FirstName, LastName, Age properties (which refer directly to the database columns).
I created the IPerson interface and used its PersonDto.
[Table(Name="Persons")] internal class PersonDto : IPerson { .... }
[Table(Name="Persons")] internal class PersonDto : IPerson { .... }
And my repository method will accept and retrieve IPerson unlike the Linq2Sql class.
IPerson somePerson = _repository.Get(someGuid); somePerson.FirstName = "SomeName"; _repository.Save(somePerson);
IPerson somePerson = _repository.Get(someGuid); somePerson.FirstName = "SomeName"; _repository.Save(somePerson);
This approach worked very well for me. Whenever I feel that I need to deviate from the DTO, I can do this quite easily because of the interface representing my object, not the DTO.
Some general pointers: Create your DTO manually ... I know this sounds crazy, but you will find that it works great with a test-based approach based on experience. DTO objects (linq2Sql) will be extremely lightweight and open to change outside of the .dbml constructor.
Keep your DTO and DataContext internal. There is no reason to publicly publish your dto (given that you have public interfaces for your repositories and domain objects). This will result in a logical separation between your domain model and data access.
Put your entire data access level in a separate project (again to ensure this separation).
Place the interface declarations in a separate project (this ensures that you donβt encounter circular links).
Hope this helps ...