views:

202

answers:

3

Take the following example:

MyDataContext context = new MyDataContext(); // DB connection established.
MyTableRecord myEntity = myDataContext.Table.FindEntity(12345); // retrieve entity

Say my entity has relationships with other tables which I would access via

foreach (var record in MyEntity.RelatedTable)

Do I need to keep my DataContext alive after the 2nd line in order to access the properties of the entities or is it safe enough to dispose of?

I understand Linq to SQL uses delayed execution hence I am wondering if it only uses delayed execution when you initially retrieve the entity or whether it uses this when accessing the related table records aswell.

Example

var userRepo = new UserRepository(); // creates new DataContext
var auditRepo = new AuditRepository(); // creates new DataContext
var activeUsers = userRepo.FindActiveUsers();
foreach (var user in activeUsers)
{
    // do something with the  user
    var audit = new Audit();
    audit.Date = DateTime.Now;
    audit.UserID = user.ID;
    auditRepo.Insert(audit);
}

My insert method in my repo calls SubmitChanges. So is the above acceptable, or is this a waste of a connection. Should I realistically do:

var userRepo = new UserRepository();
var activeUsers = userRepo.FindActiveUsers();
foreach (var user in activeUsers)
{
    // do something with user
    var audit = new Audit();
    audit.Date = DateTime.Now;
    audit.UserID = user.ID;
    user.Audits.Add(audit);
    userRepo.Save();
}

To re-use the already open DataContext? What would you do in situations where you open a high-level datacontext and then had to do some processing low level, should I pass the userRepo down or should I create a separate Repository?

+2  A: 

You don't need to dispose of the DataContext as it's a lightweight object and all internal db connections are cached. If you do dispose of it you won't be able to access the related entities.

tt83
So L2S also uses delayed execution when accessing related entities aswell?
James
Yes, it uses delayed execution unless you use the DataContext.LoadWith method
tt83
Thanks for the tip! Never realised this option was available
James
No worries! Using the LoadWith option will improve performance in most circumstances as the sql query loads all the data it needs in one go rather than running another query for each related entity as it's accessed (N+1 issue).
tt83
Say you have a scenario where you need to open 2 datacontexts at once? Is this normally a good idea or is there a better way?
James
I would try to avoid having two DataContexts open at the same time. I assume you need to retrieve some data inside a loop - if this is the case you could load the results from the first query into a memory (perhaps using select new {}) and then while looping through the in-memory collection execute the additional queries with the same DataContext.
tt83
The reason I would have 2 datacontexts open at the one time is because I am using the Repository pattern. Hence if I need to insert different items into specific tables I would need to create different repos, however, I suppose I could just expose a Save method on every repo so I could just add the specific entities in using 1 repo and just call Save
James
+4  A: 

To access fields in other tables you will need to keep the DataContext alive. Also, don't call dispose directly, use the using keyword.

using (MyDataContext context = new MyDataContext()) // DB connection established.
{
    MyTableRecord myEntity = myDataContext.Table.FindEntity(12345); // retrieve entity

    foreach (var record in MyEntity.RelatedTable)
    {
        ...
    }
}
Mark Byers
IS it always advised to use a using statement when dealing with repos? I have created custom Repositories that I am using and sometimes it doesn't seem a good idea to wrap all my code up in using statements
James
You mean you have some custom written code that only you work on and you can guarantee that it does not hold onto any resources longer than necessary if you omit the Dispose call, and never will do in the future? Then in your situation, I guess it's OK to not call using. But in general it's good practice to call using on any object that implements IDisposable. You won't leak anything if you don't: the garbage collector will clean up undisposed objects that go out of scope. But you don't know when the garbage collector will run, if ever.
Mark Byers
Yeah good point Mark, thanks.
James
A: 

Check hear if you hawe webproject: http://www.west-wind.com/weblog/posts/246222.aspx

Florim Maxhuni
Its not a web project however, its still an interesting linq on L2S.
James