How to handle exceptions using LINQ's SubmitChanges method? - c#

I am adding a new record to my department table using LINQ, this what I do:
try
{
dpt = new departement();
dpt.departementcode = tbDepartementCode.Value;
dpt.departementname = tbDepartementName.Value;
dpt.createby = "hendra";
dpt.createdate = DateTime.Now;
dpt.updateby = "hendra";
dpt.lastupdate = DateTime.Now;
Linq.departements.InsertOnSubmit(dpt);
Linq.SubmitChanges(); // error happen here, and could not catch it.
Response.Redirect("Departement.aspx");
}
catch (ChangeConflictException ex)
{
Console.WriteLine(ex.Message);
}
The problem is, even after using try and catch I still get an error screen when I enter a record which already exists in the database. How to fix it? Any ideas? Some example would be great.

If you try to submit your changes again inside the catch block, it could produce a new exception. The catch block you are already in, catch that new exception. For the new exception to be caught, you have to define a new try-catch inside your catch.
EDIT
Since the question has changed, if the catch is not catching the exception which is thrown inside Linq.SubmitChanges(), than the thrown exception is probably not of the type ChangeConflictException.

I still get an error screen when I enter a record which already exists in the database
So check your database first if the data exists, if it exists update old data, else add new data.
try
{
// Check Database first with your primary key, lets assume your check returned a
// with dptcheck
var dptcheck = from d in Linq.departments
where d.YourPrimaryKey == YourValue
select d;
dpt = new departement();
if (dptcheck.Any()) dpt = dptcheck.FirstOrDefault();
dpt.departementcode = tbDepartementCode.Value;
dpt.departementname = tbDepartementName.Value;
dpt.createby = "hendra";
dpt.createdate = DateTime.Now;
dpt.updateby = "hendra";
dpt.lastupdate = DateTime.Now;
if (!dptcheck.Any()) Linq.departements.InsertOnSubmit(dpt);
// notice you only insert data if no old value found
Linq.SubmitChanges();
Response.Redirect("Departement.aspx");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}

try below mention code it may help you.
Context.SubmitChanges(Result =>
{
if (Result.HasError)
{
CallBack(Result.Error.ToString());
}
else
{
CallBack("Done");
}
}, null);

Related

Check if .NET LDAP Bind was successfull

Current Issue:
When trying to execute a search on an LDAP Connection in .NET, the server response is that a "successfull bind" has to be made beforehand, which in my prior experience with LDAP Error messages I honestly dont buy.
The code for the search is as follows:
var req = new SearchRequest("dc=test,dc=intern", "(&(sAMAccountName=*test*))", SubTree, new string[1] { "cn" });
uSearchResults = (SearchResponse)uEntry.SendRequest(req).Entries;
dblSearchResultsCount = uSearchResults.Count;
The code for the bind is the following:
try
{
connection = new LdapConnection(new LdapDirectoryIdentifier(LdapHost, LdapPort));
connection.AuthType = 2;
connection.SessionOptions.ProtocolVersion = 2;
connection.Credential = new System.Net.NetworkCredential(strUsername, strPassword);
connection.Bind();
LogEvent("Bind", 0, "Bind most likely successfull, no exception was thrown");
}
catch (Global.System.DirectoryServices.Protocols.DirectoryOperationException ServerEx2)
{
//Logging Code
return false;
}
catch (COMException ex)
{
//Logging Code
return false;
}
catch (LdapException ex)
{
//Logging Code
return false;
}
catch (Exception ex)
{
LogEvent("Bind", 0, ex.Message);
return false;
}
As you can see, I am catching every error known to man in the bind process, which as far as I know is the only way to check if the bind worked or not. The credentials, host and port are also verified to be correct.
The connection variable has no properties or functions known to me to check if a bind was successfull. The only measure I can take if the bind worked is to check if any errors occured along the way.
How can I check in the connection variable that is of the type LdapConnection if the bind was actually successfull?
The source code shows that it keeps a _bounded boolean variable, but does not expose it. So you can't check it.
But the code for binding does show that it will throw an exception if anything goes wrong. So if no exception is thrown when you call Bind(), you know the bind was successful.

how to use a precondition check to stop next line from executing (or for whatever other reason it might be used for)

Like if I had an else if or try catch statement. How can I stop specific lines of code from executing if the statement failed or caught an unhandled exception
I already posted the question before, so I'm just reformulating.
If you don't want the program to execute a certain line of code if the try catch fails, what would you do?
try
{
PRECIO = Convert.ToDouble(TBPRECIO.Text);
CANTIDAD = Convert.ToDouble(TBCANTIDAD.Text);
CATEGORIA = Convert.ToDouble(TBCATEGORIA.Text);
}
catch
{
MessageBox.Show("NO PUEDE HABER ESPACIOS VACIOS");
TBPRECIO.Focus();
}
I think the general solution to what you're asking is that you can declare a variable outside the try block and set it inside the try block after the line you want to check executes.
bool CANTIDADRead = false;
try
{
PRECIO = Convert.ToDouble(TBPRECIO.Text);
CANTIDAD = Convert.ToDouble(TBCANTIDAD.Text);
CANTIDADRead = true;
CATEGORIA = Convert.ToDouble(TBCATEGORIA.Text);
}
catch
{
MessageBox.Show("NO PUEDE HABER ESPACIOS VACIOS");
TBPRECIO.Focus();
}
if(CANTIDADRead)
//do stuff
In your particular case though, you might be better off switching to double.TryParse:
bool PRECIOREAD = double.TryParse(TBPRECIO.Text, out PRECIO);
bool CANTIDADREAD = double.TryParse(TBCANTIDAD.Text, out CANTIDAD);
bool CATEGORIAREAD = double.TryParse(TBCATEGORIA.Text, out CATEGORIA);
This will attempt to parse the value of those strings and return whether or not the parse is successful. The out keyword means that the variable you pass in will be updated by the method, but if the parse fails it won't be the correct value.

MVC SQL connection initialization

I am working on a MVC web page that edits a SQL DB table. In my controller, I have a DB call to increment an entity table. Then if successful, creates a new row in my target table (not the entity table).
The problem I am running into is I keep getting the following error:
The ConnectionString property has not been initialized.
However this only happens after the entity table has been incremented. Not sure where to go on this, so I am hoping that by posting some code, someone would be able to help me find my error.
so here is the obligatory code:
My SQL Connection:
private SqlConnection con;
public BaseRepository()
{
con = new SqlConnection(ConfigurationManager.ConnectionStrings["SqlServerConnection"].ToString());
}
My Entity Table Increment Call:
public int GetNextId()
{
try
{
using (con)
{
DynamicParameters dynParam= new DynamicParameters();
dynParam.Add("#entity_name", "insert_object ");
con.Open();
var value = con.Execute(SP_GET_NEW_ID, dynParam, commandType: CommandType.StoredProcedure);
con.Close();
return value;
}
}
catch (Exception ex) { throw ex; }
}
Finally, here is the Row Insert Code:
public int InsertRowCode(InsertObject ccModel, UserModel appUser)
{
var value = GetNextId();
if (value == 1)
{
try
{
using (con)
//this is where the code breaks and jumps the the exception ex in my catch
{
con.Open();
var dP = new DynamicParameters();
//(add 14 dynamic Parameters here)
var result = con.Execute(SP_SAVE_CORRECTION_CODES, dP, commandType: CommandType.StoredProcedure);
con.Close();
return result;
}
}
catch (Exception ex)
{
throw ex;
}
}
else { throw new Exception("Busted"); }
}
Any help is greatly appreciated. TIA
Don't use shared connection objects.
When you exit this block:
using (con)
{
//...
}
That connection object is now disposed and can't be used anymore. Don't worry about trying to optimize your connections, the connection pool does a very good job of that already. Create your connection objects where you need them, use them, and dispose them in a tight scope:
using (var con = new SqlConnection(connectionString))
{
//...
}
As a side note, this is superfluous:
catch (Exception ex)
{
throw ex;
}
That catch block isn't doing anything for you, and is actually deleting important information about the exception. Just remove that try/catch entirely.
If, on the other hand, you ever do want to do something with an exception before re-throwing it, just use the keyword throw by itself:
catch (Exception ex)
{
// log something, etc.
throw;
}
This would allow the exception to continue up the stack unmodified, preserving the actual error information.

Optimistic concurrency returning a value

I have an optimistic concurrency method from which I need to return a value. I am getting an error indicating the return variable is not in scope.
private static string GenerateCustomerId(string contextPath)
{
var retryMaxCount = 3; // maximum number of attempts
var cycles = 0; // current attempt
Exception exception = null; // inner exception storage
while (cycles++ < retryMaxCount) // cycle control
{
try
{
Content sequenceContent = Content.Load(contextPath);
int currentSequence;
int.TryParse(sequenceContent["LastSequenceNo"].ToString(), out currentSequence);
currentSequence++;
string currentDate = DateTime.Now.ToString("ddMMyyyy");
string customerID = string.Format("{0}{1}", currentDate, currentSequence);
//Save back to content with new update
sequenceContent["LastSequenceNo"] = currentSequence.ToString();
sequenceContent["LastCustomerID"] = customerID;
sequenceContent.Save();
}
catch (NodeIsOutOfDateException e)
{
exception = e; // storing the exception temporarily
}
return customerID; //"**Customer ID does not exist in current context**"
}
// rethrow if needed
if (exception != null)
throw new ApplicationException("Node is out of date after 3 attempts.", exception);
}
How can I return the value of CustomerID?
Just move the return statement into the try block - and then add an extra throw statement at the very end of the method; if you ever reach the end of the method without an exception, that indicates something very strange going on. Or you could just make the final throw unconditional, of course:
private static string GenerateCustomerId(string contextPath)
{
var retryMaxCount = 3; // maximum number of attempts
Exception exception = null; // inner exception storage
for (int cycles = 0; cycles < retryMaxCount; cycles++)
{
try
{
...
// If we get to the end of the try block, we're fine
return customerID;
}
catch (NodeIsOutOfDateException e)
{
exception = e; // storing the exception temporarily
}
}
throw new ApplicationException(
"Node is out of date after " + retryMaxCount + " attempts.", exception);
}
As an aside, I'd personally avoid ApplicationException - I'd either just rethrow the original exception, or create a dedicated RetryCountExceeded exception or something similar. ApplicationException was basically a mistake on Microsoft's part, IMO.
(Also note that I've converted your while loop into a for loop for simplicity. I would certainly find the for loop easier to read and understand, and I suspect most other developers would feel the same way. I'd consider making retryMaxCount a constant in your class rather than a local variable, too.)

how to ignore errors in SaveChange EF4

Please see to example1. If some of the data will be entered incorrectly, EF4 will not survive nor any record.
The question: whether as a force to ignore an error in one record and continue on.
example1:
foreach (var tag in split)
{
context.NameToResourcer.AddObject(new NameToResourcer()
{
id_resource = resource.id,
name = tag
});
}
context.NameToResourcer.AddObject(new NameToResourcer()
{
id_resource = resource.id,
name = ExtractDomainNameFromURL(resource.url)
});
try
{
context.SaveChanges();
}
catch (UpdateException ex)
{
}
catch (Exception ex)
{
throw;
}
example2 alternative:
foreach (var tag in split)
{
try
{
context.NameToResourcer.AddObject(new NameToResourcer()
{
id_resource = resource.id,
name = tag
});
context.SaveChanges();
}
catch (UpdateException ex)
{
}
}
try
{
context.NameToResourcer.AddObject(new NameToResourcer()
{
id_resource = resource.id,
name = ExtractDomainNameFromURL(resource.url)
});
context.SaveChanges();
}
catch (UpdateException ex)
{
}
Context behaves like unit of work. It means that when you modify data and store them with the single call to SaveChanges you are telling EF that you want atomic operation - either all changes are successfully saved or all changes are rolled back. EF use a transaction internally to support this behavior. If you don't want this behavior you cannot save all data with single call to SaveChanges. You must use separate call for each atomic set of data.
One possible solution is to disable validation on saving.But I don't recommend it.
db.Configuration.ValidateOnSaveEnabled = false;

Categories

Resources