views:

58

answers:

1

I have an n-layered asp.net application which returns an object from my DAL to the BAL like so:

public IEnumerable<SourceKey> Get(SourceKey sk)
{
    var query = from SourceKey in _dataContext.SourceKeys
                select SourceKey;

    if (sk.sourceKey1 != null)
    {
        query = from SourceKey in query
                where SourceKey.sourceKey1 == sk.sourceKey1
                select SourceKey;
    }

    return query.AsEnumerable();
}

This result passes through my business layer and hits the UI layer to display to the end users. I do not lazy load to prevent query execution in other layers of my application.

I created another function in my DAL to delete objects:

public void Delete(SourceKey sk)
{
    try
    {
        _dataContext.DeleteObject(sk);
        _dataContext.SaveChanges();
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message + " " + ex.StackTrace + " " + ex.InnerException);
    }
}

When I try to call "Delete" after calling the "Get" function, I receive this error:

New transaction is not allowed because there are other threads running in the session

This is an ASP.Net app. My DAL contains an entity data model. The class in which I have the above functions share the same _dataContext, which is instantiated in my constructor. My guess is that the reader is still open from the "Get" function and was not closed. How can I close it?

In my UI layer, I loop through the results and attempt to delete them like so:

foreach(SourceKey sk in skm.Get(new SourceKey()))
{
    Debug.WriteLine(sk.sourceKey1);

    skm.Delete(sk);
}

Edit

The error is occuring on this line:

_dataContext.DeleteObject(sk);
+1  A: 

I suspect this is to do with the handling of the query by Linq. I'm guessing based on articles I've read in the past, but I think that your query is lazily executed - the query is opened from the point that the enumerator is first used (the first MoveNext call), and isn't closed until enumeration completes.

If you're in control of the enumeration, you could ensure that the enumerator completes and see if that makes any difference. Or, more likely, there's configuration somewhere that might control how the query runs, but that's beyond what I've looked at.

Dan Puzey
It was my understanding that the query would have been executed on the AsEnumerable(). I did take the delete out of my foreach loop and it worked
Chris Klepeis