I'm having some problems with DataContexts using linq to sql for an asp.net c# web application.
I first had problems with exceptions being thrown as I didn't dispose of the DataContext, same errors as in this question. I was using a static DataContext which was probably why it wasn't disposed of properly, and after reading this and several other articles I wrapped all calls in using statements to be sure they'll get disposed of.
However, now I got problems when I need to update a foreign key as the DataContext has already been disposed of. I'm not sure why it's been disposed of already, and what the best practice would be to do in this scenario so any ideas would be greatly appreciated!
Short example here:
UPDATE: I think my example was too confusing when I tried to make it as short as possible so here's a longer and hopefully better example:
private static void SendTexts(List<TextAlert> TextQueue)
{
using (THTDataContext db = new THTDataContext())
{
foreach (TextAlert text in TextQueue)
{
try
{
// do IntelliSMS stuff
// set status to 'sent'
text.Status = 1;
db.SubmitChanges();
}
catch (IntelliSMSException ex)
{
// set status to 'failed'
text.Status = 2;
db.SubmitChanges();
}
}
}
}
Thanks,
Annelie
You probably need to attach the incoming MyThing to your new context. Something like this might work:
private static void DoMyStuff(MyThing thing)
{
using (MyDataContext db = new MyDataContext())
{
db.MyThings.Attach(thing);
thing.Status = 1;
db.SubmitChanges();
}
}
Once it's attached, the context should be able to track changes to it and, on the Submit, store them.
If this doesn't resolve the "already disposed" exceptions, then you might try "detaching" the MyThing before disposing of the old context. Note that if you have to go this route, however, the lifecycle of your DataContext is probably wrong, as entities are not designed to move about between contexts in the same app domain.
If you're interested in understanding the attach/detach business a bit better, MSDN's Dinesh Kulkarni has a short blog post about it.
Yikes! If an exception was thrown while trying to update an entry in the database, do you really think it's a good idea in the exception handler to try and update an entry in the database?
As for what's going on here, what's the source of thing? Did it come from a query that was executed on another instance of MyDataContext? If so, that's your problem right there.
Related
I implemented a DataGridView some time ago. It works nice. Now I was doing some heavy-load testing, but it failed. It throws exceptions everywhere, at least when it tries to load the data.
Problem: DataContext Refresh
There is a method where I refresh the the data inside the DataGridView.
One exception tells me there is already a DataReader open, which I have to close first.
The second exception tells me "the operation cannot be performed during a call to submitchanges".
The problem is that I am not working with DataReaders myself, I am using the approach you see below:
this.bindingSource.EndEdit();
this.bindingSource.DataSource = null;
// DataControl is my controler where the table is stored. It is a singleton.
DataControl.Instance.m_DBTable.Context.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, DataControl.Instance.m_DBTable);
this.bindingSource.ResetBindings(false);
this.bindingSource.DataSource = DataControl.Instance.m_DBTable;
I hope someone can help me on this one. Feel free to ask for more details if needed.
Thanks
More exceptions thrown (not only on that method, but on the same form.)
Internal connection fatal error
Sql DateTime-Overflow (must be between 1/1/1753 and 21/31/9999) (I really do ALWAYS initialize all my date-time variables!)
Invalid reading operation when there is no data available.
No reference exception.
any time you are getting errors relating to this wrap your datareader in a using statement. This goes for any reader / writer
using(var daraReader = new DataReader())
{
// Use your data reader here, it will not be left open
}
DataContext isn't actually designed to be singleton Using a Singleton pattern to Linq to Sql Data Context. That's the first thing you should consider in your code.
If it doesn' work - try to at least dissect the problem area(http://ericlippert.com/2014/03/05/how-to-debug-small-programs/). Do not bind the data. Just try to dump them into a file or somewhere else. We will be sure that the problems are not caused by binding.
If it won't work also then it is quite possible you are having problems due to concurrency issues in LINQ to SQL and your database. Looks like standard locks and mechanisms does not work as intended. Or they work too diligently.
There are few decent articles http://blogs.msdn.com/b/matt/archive/2008/05/22/into-to-linq-to-sql-optimistic-concurrency.aspx, http://www.codeproject.com/Articles/38299/How-To-Handle-Concurrency-in-LINQ-to-SQL that explain concurrency in LINQ.
I hope that some of it could help.
Is it possible to get run-time information about where a method has returned?
I mean, if the method returned after running all its lines of code, or because of an earlier
return statement that occurred due to some condition.
The scenario is using interceptor for creating UnitOfWork that should exists in method scope.
For example, lets consider this code:
[UnitOfWork]
public void Foo()
{
// insert some values to the database, using repositories interfaces...
DoSomeChangesInTheDataBaseUsingRepositories();
var result = DoSomethingElse();
if (!result) return;
DoMoreLogicBecuseTheResultWasTrue();
}
I have interceptor class that opens thread static unit of work for methods that are flagged with [UnitOfWork] and when the scope of the method ends it run commit on the UoW and dispose it.
This is fine, but lets consider the scenario above, where for some reason a programmer decided to return in the middle of the method due to some condition, and in that scenario the changes made by the repositories should not be persisted.
I know that this can indicate wrong design of the method, but be aware that it is a possible scenario to be written by a programmer and I want to defend my database from these kind of scenarios.
Also, I don't want to add code to the method itself that will tell me where it ended. I want to infer by the method info somehow its returned point, and if it is not at the end of its scope the interceptor will know not to commit.
The simple answer is use BREAKPOINTS and Debugging.
Edit:- As mentioned by Mels in the comments. This could be a useful suggestion.
If your application is very timing-sensitive, set conditional breakpoints such that they never actually stop the flow of execution. They do keep track of Hit Count, which you can use to backtrace the flow of execution.
Just for your attention. From the microsoft site:-
For those out there who have experience debugging native C++ or VB6
code, you may have used a feature where function return values are
provided for you in the Autos window. Unfortunately, this
functionality does not exist for managed code. While you can work
around this issue by assigning the return values to a local variable,
this is not as convenient because it requires modifying your code. In
managed code, it’s a lot trickier to determine what the return value
of a function you’ve stepped over. We realized that we couldn’t do the
right thing consistently here and so we removed the feature rather
than give you incorrect results in the debugger. However, we want to
bring this back for you and our CLR and Debugger teams are looking at
a number potential solutions to this problem. Unfortunately this is
will not be part of Visual Studio 11.
There are a couple ways that normally indicate that a method exited early for some reason, one is to use the actual return value, if the value is a valid result that then your method probably finished correctly, if its another value then probably not, this is the pattern that most TryXXX methods follow
int i;
//returns false as wasn't able to complete
bool passed = int.TryParse("woo", out i);
the other is to catch/trhow an exception, if an exception is found, then the method did not complete as you'd expect
try
{
Method();
}
catch(Exception e)
{
//Something went wrong (e.StackTrace)
}
Note: Catching Exception is a bad idea, the correct exceptions should be caught, i.e NullReferenceException
EDIT:
In answer to your update, if your code is dependant on the success of your method you should change the return type to a boolean or otherwise, return false if unsuccessful
Generally you should use trace logs to watch you code flow if you cant debug it.
You could always do something like this:
private Tuple<int, MyClass> MyMethod()
{
if (condition)
{
return new Tuple<int, MyClass>(0,new MyClass());
}
else if(condition)
{
return new Tuple<int, MyClass>(1, new MyClass());
}
return new Tuple<int, MyClass>(2,new MyClass());
}
This way you´ll have an index of which return was returning your MyClass object. All depends on what you are trying to accomplish and why - which is at best unclear. As someone else mentioned - that is what return values are for.
I am curios to know what you are trying to do...
If I'm doing something with the inserted values during an EntityDataSource's Inserted event, should I wrap e.Entity in a using() statement? I can't tell. Is that "in context"?
Should it be (as I've seen in other examples):
myEntity NewRecord = (myEntity)e.Entity;
myVar = NewRecord.DataValue;
Or is it appropriate practice to do:
using (myEntity NewRecord = new e.Entity())
{
myVar = NewRecord.DataValue;
}
(Don't think that syntax would be totally correct. Don't want to have to look up how that would work just to ask.)
From the MSDN documentation, all I can gather is that e.Entity is an object that is ... the entity. Helpful. So does it open a new connection and the whole rest of the package that I would assume a new entity would require?
In general, I'd say yes do it. Best practice? Yes for sure. However, the answer is more like "it depends". As a rule, anytime you use an object that implements IDisposable one should wrap it in a using statement unless you plan to keep the object between method invocations.
In the stateless world of the web (MVC) where I tend to live, I try to wrap my DbContext in a using statement. In Winforms/WPF I'm sure there are reasons to persist until some event takes place. These should be exceptions to the rule.
Using is used when you want to make sure you call the Dispose method when the program execution leaves the scope of the using.
For example say your code might throw an exception and you wanted to make sure it still called Dispose(). A using statement would guaranty it.
So if myEntity implemented iDisposable you would want to use the using statement. If it doesn't you wouldn't need to, but still could, I think... lol.
I have the following code:
CustomerService service;
public CustomerService Service
{
get
{
if (this.service == null)
{
this.service = new CustomerService();
}
return this.service;
}
}
public DataTable GetCustomers()
{
return this.Service.GetCustomers();
}
Now the question is: if I wrote the above method as follow (without "this"), it's giving me an error : instance is not reference to an object.
public DataTable GetCustomers()
{
return Service.GetCustomers(); // this will spell the error "instance is not reference to an object"
}
Does anyone know? also it only happens while running via IIS and not from casini web server (VS 2010).
The presence or absence of this cannot explain the error you are witnessing. In this situation they mean exactly the same thing and will compile to the same IL code. Check the assembly using .NET Reflector to verify this if you wish. The error is occurring at random, probably due to a race condition.
One thing I can immediately see is that if you are running this code from multiple threads then it looks like you have a race condition here:
if (this.service == null)
{
this.service = new CustomerService();
}
return this.service;
In the multithreaded case you would need to lock otherwise you could get two CustomerService objects. I'm not sure if this explains your error, but it certainly could create confusion. Race conditions can occur in one environment but not in another as the frequency of the error can depend on the type of the hardware and on what other processes are running on the server.
You may also have other race conditions in the code you haven't posted. Don't use this lazy initialization technique without locking unless you are sure that you have only one thread.
You probably have a name conflict with another 'Service' (class or namespace). The use of this solves it.
I'm a bit skeptical about the difference between Cassinin and IIS, have you carefully checked that?
Something like this should be in a singleton. Which would resolve many issues like threading if implemented correctly and would make the implementation and readability of the code much better.
Thanks
-Blake Niemyjski (.netTiers team member)
I fiddled a bit with your code in Visual Studio and I couldn’t even get a name conflict to produce the error message you described. I can’t think of any case in which “this.X” can ever be different from “X” except when “X” is a local variable or a method parameter.
Would the CustomerService class derive from a base class called Service? If so, then that's the problem.
Can someone please explain the below to me. First is how I call the method and the second bit is the LINQ Method.
My curiousity stems from the fact that I get a context error if I un-comment the using portion.
Why? I apparently do not fully understand using and context's. And I would like to better understand this.
Guid workerID = new Guid(new ConnectDAL.DAL.Security().GetUserIDByUserLogin(HUD.CurrentUser));
var myMembers = BLLCmo.GetAllMembers(workerID);
if (myMembers.Rows.Count != 0)
{
dgvMyMembers.DataSource = myMembers;
}
else
{
var allMembers = BLLCmo.GetAllMembers();
dgvMyMembers.DataSource = allMembers;
}
internal static CmoDataContext context = new CmoDataContext();
public static DataTable GetAllMembers()
{
DataTable dataTable;
//using (context)
//{
var AllEnrollees = from enrollment in context.tblCMOEnrollments
select new
{
enrollment.ADRCReferralID,
enrollment.ClientID,
enrollment.CMONurseID,
enrollment.CMOSocialWorkerID,
enrollment.DisenrollmentDate,
enrollment.DisenrollmentReasonID,
enrollment.EconomicSupportWorkerID,
enrollment.EnrollmentDate
};
dataTable = AllEnrollees.CopyLinqToDataTable();
//}
return dataTable;
}
"using" blocks automatically dispose of the object you're using. Since you didn't give further details on what the exact error is, I'm betting its related to the fact that the "using" will dispose of your "context", and then later you'll try to use your context again.
Data Contexts should be used atomically. They're already internally coded to be efficient that way, there's usually no justifiable reason to have one as long-running as you do. The reason you see most samples that use a "using" is because they have the data context initialized immediately before the using (or in it) and then don't try to referenced the disposed context.
As a final note, disposing of objects causes them to release all their internal memory references (such as open connections, cached data, etc).
//Our context exists right now ... unless we've already called this method since the app started ;)
var myMembers = BLLCmo.GetAllMembers(workerID); // Context is disposed at the end of this call
if (myMembers.Rows.Count != 0)
{
dgvMyMembers.DataSource = myMembers; //No prob, we didn't call our function again
}
else
{
var allMembers = BLLCmo.GetAllMembers(); // Oops, our context was disposed of earlier
dgvMyMembers.DataSource = allMembers;
}
You get an error if you use using because the context is disposed the second time it's called by GetAllMembers().
If you need to dispose the context I sugest you create one on the fly in the GetAllMembers() as opposed to having a static context.
Check out the documentation of IDisposable and using.
Here's a link to an article that might help you with Lifetime Management of DataContext.
I have had this problem and did not understand it either at that time. I just removed the using and it worked. The problem was Lazy Loading. The DataContext gave me an entity, but later I tried accessing a property of a parent entity (in the sense of a Foreign Key). Because this parent entity was not loaded the first time, it tried to get it but the DataContext was gone. So I used a DataLoadOptions. If I knew I needed a related entity, I loaded it with the original entity.
Ex: You ask for an invoice to your datacontext, but later you want to access the client's name, like in invoice.Client.Name. The client has not been loaded, so the name is not available.
DataLoadOptions are also important for performance, if you need this related entity in a loop, you'll go back to the DB as many times as you loop if you do not pre-load the child (or parent) entity.