Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Currently I'm starting a new system on my company, and we are using a good separation between models, views and controllers, basically using Asp.Net MVC 3 for the user UI, and a C# class library for the model.

The question is about "modelling a model".

We are using Linq-to-SQL as a Data Access Layer, and modelling entities over this DAL. Example:

    // DAL, an autogenerated .dbml file
    ...
    public System.Data.Linq.Table<TB_USER> TB_USERs {
       get {
          return this.GetTable<TB_USER>();
       }
    }
    ...

And we are mapping this table on an entity, like below:

    public class User {
       // Entity, mirroring a .dbml table
       public static IEnumerable<User> GetAll() {
           var db = new MyDataContext();
           var userList = (from u in db.TB_USERs select u).ToList();
           IEnumerable<User> retorno = lista.ConvertAll(u => (User)u);
           return retorno;
       }

       // Active Record ?
       public static User Save(User user) { ... }
    }

Is this kind of modelling correct ? It feels like I'm repeating myself by having 2 entities meaning the same thing (User and TB_USER), but TB_USER is the raw representation of the database table that persists the User entity.

And the GetAll method, a static method created on the entity with the sole purpose of retrieving all of them. That means that if I want to retrieve data using a filter, for example, I have to create another GetDataBy... method.

And what about the Save method ? I know it's supposed to save the state of one User, but what if I have to save some random User object along with other objects to make a transaction ?

Shouldn't this kind of transaction control be in the database ?

share|improve this question
    
Separaation of UI to me would be letting the UI being unaware of the table design. Which mean you create poco object with the fields useful to the UI. In BL (model?) You just fetch the data you want from DAL and transform it manually to the corresponding poco type. Of course you retun the result as a Ienumerable<type> or whatelse intended. You can then do whatever you want to UI or DAL without directly affect each other. –  Independent Dec 22 '11 at 6:48
    
@Jonas, we understand the MVC concept, and we understand the saparation between the Linq-to-SQL classes and our POCO's, but my question is about how common is this kind of modelling we are using. There are 2 specific questions: What kind of transaction control issues can we have with this kind of modelling, and should a POCO contain this kind of data-retrieval / data-persistent methods ? –  Machado Dec 22 '11 at 11:57
add comment

2 Answers

If you are going to stick with LINQ-to-SQL you probably want to use the linq-to-sql classes as your entities. That is rename TB_USER to User and you then wrap the interaction with LINQ-to-sql in repositories, i.e. a UserRepository with a GetById, GetByUserName, Save, and similar methods - depending on your specific needs. This keeps the data access in one place.

With LINQ-to-sql beware of the temptation to have LINQ expressions that go off and query the DB scattered across your code base. LINQ-to-sql seems to encourage that in my experience. But that leads to very tight coupling.

If you want a cleaner cut between your domain entities and the DB, I'd really recommend moving to another ORM. My personal preference with a SQL Server on the backend would be NHibernate.

share|improve this answer
    
We are resisting the temptation to use the Linq-to-SQL generated classes as or BL, that's the reason to use our POCO's - this and encapsulating the Linq queries inside the POCO's only. But I'm concerned about the transaction issues with this kind of modelling: If I have to persists 4 Users in one single transaction, how is this usually done with Linq-To-SQL ? –  Machado Dec 22 '11 at 11:51
    
The repositories is where I'd put linq-to-sql queries –  Christian Horsdal Dec 22 '11 at 18:37
    
Is this a Web app or a desktop app or ..:? –  Christian Horsdal Dec 22 '11 at 18:37
1  
@Machado Repo is a kind of "container for data" which you call from i.e. UI and the repo is, in turn, recieve the data from DAL. Here you are free to form new classes (poco) with any kind of structure you which, against the UI. It looks, of your description, that you just "forward" an identic structure (or even same entity objects). The dbml files should never be manually changed other than that you attach partial classes or decorate with a interface implementation (which, in turn, means that the dbml files itself is intact). –  Independent Dec 23 '11 at 12:35
1  
@Machado Without exactly understand what "another class" you have in mind, it sounds correct. Because you (in the repo-class) re-define DAL-entities to your own typed poco, you don't need to attach reference to the DAL, from your UI. That's a big point of the pattern. –  Independent Dec 23 '11 at 13:44
show 7 more comments

I think Christian came up with a good answer to your question. Based on the exchanged comments there may be some things worth explanation in the pattern you try to use.

POCO is it's name. Plain pure objects which have no logic inside. They just concsist of getter/setters you want to expose at the, in your described case, UI. The repository is an additional class which is the place for the logic of data between DAL and presentation. This seen together with the ORM objects, yes there are a lots of classes involved. The ORM classes though, is nothing but the UML designer to take care of. The Repo and poco classes are more interesting because the going to the interface between your ORM and your UI.

I.e. I can have a POCO named Resident, which can have fields that came from several tables (Entity objects) in DAL. I.e. Location for the address and apartment specifications and also User, which helds the name, emailadress and such information. The UI will never know that there exist a user-table-design at all. Sometimes the Pocos can feel like repeating the same object over again (Because they contain same fields to the UI as to the DAL).

Your correct about the GetAll(), Save() methods, they should be in the repo-class. I.e. Save() could be Save(PocoType poco), which inside the method, store the poco object to the corresponding DAL entity fields. GetAll() return the poco object, inside the method there are logic to open DAL, fetch data and transform to the POCO type.

I also, sometimes, use a IEnumerable SomeEntity { get { .. } } which inside the getter open the DAL and transform to PocoType. From UI i have a fully available linq context. like var result = instantiatedType.SomeEntity.Where(u=>u.LoggedIn > DateTime.Now.AddDays(365)) (i tooked this right from head, I may have missed some syntax details).

Ok I hope I added something useful and, at least, correct info :). It's in middle of the night and the Christmas day was arrived!

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.