views:

180

answers:

1

I'm trying to figure out a clear way of populating my model classes from LINQ to SQL generated objects. My goal is to keep my Models and LinqModels separate. Say I have the following models:

public class Person {
    public List<Account> Accounts {get; set;}
}
public class Account {
    public List<Purchase> Purchases {get; set;}
}
public Purchase {
    public String Whatever {get; set;}
}

Now, I also have nearly identical data models generated by LINQ to SQL. So if I want to populate a Person object I'm going to add a getter method within the DataContext partial class:

public Person GetPersonByID(int personID) {
    ....
}

How we populate this Person object and its children properties throughout the rest of the application is done like this:

public Person GetPersonByID(int personID) {
    Person res = 
        from p in Persons 
        select new Person() {
            Accounts = (
                from a in p.Accounts
                select new Account() {
                 Purchases = (
                     from m in p.Purchases
                     select new Purchase() {
                         Whatever = m.Whatever
                     }
                 ).ToList()
                }
            ).ToList()
        }
    return res;
}

So for each child property we need to extend the query. What I would really prefer is if I could do something more like this:

public Person GetPersonByID(int personID) {
    return new Person( this.Persons.SingleOrDefault( p => p.ID == personID ) );
}
....
public class Person {
    public Person(DataModels.Person p) {
        Accounts = (from a in p.Accounts select new Account(a)).ToList();
    }
}
public class Account {
    public Account(DataModels.Account a) {
        Purchases = (from r in a.Purchases select new Purchase(r)).ToList();
    }
}
public class Purchase {
    public Purchase(DataModels.Purchase r) {
        Whatever = r.Whatever
    }
}

This is much more manageable, but the initial GetPersonByID call does not return the data I need to populate these child objects. Is there any way around this?

Or is there a better alternative to populating model objects using LINQ to SQL?

*** Sorry if my code examples are not quite right*

A: 

What you are looking for is called "persistence ignorance".

It is a valued property of a design, specifically in the DDD (Domain Driven Design) circles.

You can achieve it for example using LinqToSQL's XML mapping capabilities, where you do not generate data classes and indicate to LTS how to map your domain classes (Account, Purchase etc) to the database directly.

Because of LinqToSQL's limited capabilities in terms of mapping options (specifically the lack of value objects, the limitation on the inheritance mapping and the lack of Many-to-Many relationship support), it might or might not work in your case.

Another option, if you have your LTS-generated classes and your domain classes as above, is to look into Automapper, which can help getting some of the repetitive work out of the way.

Denis Troller