Entity Framework - explain my code - c#

Is this a correct understanding of what this code does - and is it the correct way to update a row which has a URLPath of url so that the IsInProcessing column is true?
I haven't actually tried this code yet. Before I do, I want to try and understand it! It is pieced together from various sources.
The code:
using(var db = new DamoclesEntities())
{
var urls = db.URLS;
var result = urls.FirstOrDefault(u => u.URLPath == url);
result.IsInProcessingQueue = true;
db.SaveChanges();
}
What I think is happening here is within the using I am instantiating the DamoclesEntities() class as var db.
I then instantiate the db.URLS (class / table) to the var urls.
I then find the first row where the URLPath (column) contains url, and that row is assigned to result.
I change that row's IsInProcessingQueue (column value) to true;
Finally, I save the changes to the database.

it is almost correct, but keep in mind, that FirstOrDefault will return null value in case if there is no rows found by specified criteria - URLPath == url.
So in this case next row will produce NullReferenceException.
Just add check of result for a null and do result.IsInProcessingQueue = true;db.SaveChanges(); only if result != null

Related

Deleting cell value using EntityFramework

This is my database table called 'AssignedExercises':
I'm trying to delete this value:
This is my code...
var b = db.AssignedExercises.Where(m => m.Data_UserID.Equals(3)).FirstOrDefault();
db.AssignedExercises.Remove(b);
db.SaveChanges();
but it deletes a whole row. How should I change it?
Thanks!
You are explicitly removing the row, which is represented by the entity object. Columns on the other hand are represented by properties on the object. As a result, you need to update the property on the object itself. Also, you can use FirstOrDefault() directly...the Where() is redundant.
var b = db.AssignedExercises.FirstOrDefault(m => m.Data_UserID.Equals(3));
if (b != null)
b.Monday = null;
db.SaveChanges();
I'm assuming you want to clear out the value, not "delete the cell"? You can't really "delete the cell" because it is represented by the column "Monday". So for that row, you can clear the value out (e.g. set to NULL or an empty string perhaps?). If you were to "delete" it, you would be removing the entire column for all rows.
I would simply do this:
var b = db.AssignedExercises.Where(m =>m.Data_UserID.Equals(3)).FirstOrDefault();
b.Monday = ""; // if you want empty string, or set to DbNull
db.SaveChanges();
That's the expected behaviour. You can edit the value using:
b.Monday = null;
and then call
db.SaveChanges();
You have to update the value instead of using remove. Remove, as you have discovered, deletes the row.
var b = db.AssignedExercises.Where(m => m.Data_UserID.Equals(3)).FirstOrDefault();
b.Monday = NULL; //or DbNull if you need to
db.SaveChanges();

Searching for record in c# Winform (Entity Framework)

I have a c# winform with textboxes, connected via Entity Framework to a table, called Candidates (it has 700 records).
I'm using a BindingSource named candidatesBindingSource. Everything works as I want.
There is just one thing. I'm trying to implement searching candidates with surnames. So i have a Textbox, called textSurname and a Button with this code
for searching through my records:
var searchResults = (from a in _context.Candidates where (a.Surname.Contains(textSurname.Text)) select a.Id).ToList();
if (searchResults.Count > 0)
{
// Id of a record in searchResults is correct
var position = searchResults[0];
// This line moves focus to a wrong record
candidatesBindingSource.Position = position; //
}
If a record is found, I can get its Id. And here I have a problem. How can I reposition my candidatesBindingSource to the
record with the Id from my searchResults? For example, if I have an Id = 2638, the code above repositions my candidatesBindingSource
to the last record. I'm suspecting that this part candidatesBindingSource.Position actualy works as recordcount (700 in my table)
and is unable to go to the record nr. 2638 (not to the record with this Id). Am I right? So how can I implement a GOTO record with my found Id?
Do I really have to use a For loop with MoveNext command to compare my searched Id with all Id's?
Any hint would be very appreciated.
Ok, so this is how you initialize you binding source
candidatesBindingSource.DataSource = _context.Candidates.ToList();
Then you don't need to search the database, you can search the data source list using the List.FindIndex method like this:
var candidateList = (List<Candidate>)candidatesBindingSource.DataSource;
var searchText = textSurname.Text;
var firstMatchIndex = candidateList.FindIndex(c => c.Surname.Contains(searchText));
if (firstMatchIndex >= 0)
candidatesBindingSource.Position = firstMatchIndex;
I think you should set to candidatesBindingSource.Position index of item and not id.
That post will help you to get index of item correctly, witout read whole data again.
Get Row Index in a list by using entity framework
Also you can try get index from your binding source.
If you create a list out of your context it will have the same indexing as the databinding you set on your form. To set your form to look at the result of your search you can use the a match from the FindIndex() method of the list, and then set your .Position to that index.
using (Candidates _context = new Candidates())
{
var candidateList = _context.Candidate.ToList();
var firstCandidateMatchIndex = candidateList.FindIndex(c =>
c.Surname.Contains(textSurname.Text));
if (firstCandidateMatchIndex >= 0)
candidateBindingSource.Position = firstCandidateMatchIndex;
}

Getting modified values dynamically

I have got a problem. While updating a row in the table by Linq To Sql,
I want to know the only changed fields.
Suppose I have 25 fields in a page but I only updates 3 fields and at the time of updation, I need to get only those 3 fields, it's old value + it's modified or new value.
Can IT be possible in the Linq To Sql.
I was searching the things on internet and have come to know about DB.GetChangeSet() but it just gives me the modified row.
I have checked other questions related to same from here but I did'nt get the way they were using I also tried but it is giving me error "Sequence contains no elements"
I tried in this way::
where TableClass ObjTbl in the function parameter is the Object containing the new values from the model.
public int UpdateDetails(int Id, TableClass ObjTbl)
{
using (DataContext DB = new DataContext())
{
var Data = DB.TableClass.Where(m => m.PkId == Id).FirstOrDefault();
Data .FirstName = ObjTbl.FirstName;
Data .MiddleInitials = ObjTbl.MiddleInitials;
Data .FkClientID = ObjTbl.FkClientID;
Data .LastName = ObjTbl.LastName;
DB.SubmitChanges();
TableClass instance = DB.GetChangeSet().Updates.OfType<TableClass>().Where(m => m.PkId == Id).First();
DB.TableClass.GetModifiedMembers(instance);
}
}
You need to check for your changes before you call SubmitChanges.
Also, in your example the line
TableClass instance = DB.GetChangeSet().Updates.OfType<TableClass>().Where(m => m.PkId == Id).First();
will throw an exception if nothing was changed, otherwise it will return the record you are amending ie, Data, so you may as well just do something like
ModifiedMemberInfo[] changes = DB.TableClass.GetModifiedMembers(Data);
If nothing has been changed, then this will return an empty array, rather than throw an exception.

Checking to see if string exists in db using linq

Here's my attempt:
public void ReadLot(LotInformation lot)
{
try
{
using (var db = new DDataContext())
{
var lotNumDb = db.LotInformation.FirstOrDefault(r => r.lot_number.Equals(r.lot_number));
if (lotNumDb.lot_number != null && lotNumDb.lot_number.Length == 0)
{
Console.WriteLine("does not exist. yay");
var lotInfo = db.LotInformation.FirstOrDefault(r => r.lot_number.Equals(lotNumber));
}
else if (lotNumDb.lot_number.ToString().Equals(lot.lot_number))
{
errorWindow.Message = LanguageResources.Resource.Lot_Exists_Already;
dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);
}
Here what I want to do:
When the user uploads a file, I check if the deserialized string from memory is a duplicate in the database or not. If it is, pop up a dialog box saying it's a duplicate/already exists and have nothing happen afterward. If it is not a duplicate, proceed with application. Also, if the column in the table in the database is null, store the lot number there and proceed.
I noticed a few things. If the database is empty and I run the above, I get a null exception because I'm trying to find a lot number in db that is not there. How do I change the code above so that if I check in db and the column is null, then just add the number and not throw an exception when comparing. I think that might be the only problem right now.
I'm not sure what this is supposed to be doing, but you don't need it:
var lotNumDb =
db.LotInformation.FirstOrDefault(r => r.lot_number.Equals(r.lot_number));
Instead, just check for the existance of the lot_number passed to the method, and use Any to determine whether there were any matches. If it returns true, then the lot number is already in the database.
// Check for duplicates
var isDuplicate = db.LotInformation.Any(r => r.lot_number == lot.lot_number);
if (isDuplicate)
{
// Inform user that the lot_number already exists
return;
}
Console.WriteLine("does not exist. yay");
// Store the lot_number in the database
bool lotNumDbExists = db.LotInformation(r => r.lot_number.Equals(r.lot_number)).Any;
or .exists
This should return either a true or false of if it exists.

C# How do I remove values for a specific item in the database

I'm having problems deleting from my database
I have the following
Member thisMember = db.Members.First(m => m.MemberID == member.MemberID);
db.Members.Remove(thisMember.Name);
db.Members.Remove(thisMember.LastName);
But I keep getting an invalid arguments error. Can someone assist me?
Thanks!
db.Members.Remove is used to remove whole record (row/object) from data source. So you can remove whole member like this:
db.Member.Remove(thisMember);
If you want to set values of thisMember then you can do it like this:
Member thisMember = db.Members.First(m => m.MemberID == member.MemberID);
thisMember.Name = "";
// provided that it allows null value
thisMember.LastName = null;
// save changes in data source
db.SaveChanges();

Categories