Null on updated fields - c#

I am trying to update one single field in a table but it's giving me an error saying that the other content is null. I'm trying to update one single field from a table and leave the other fields as they were.
Code so far:
var user = new User() { CardNumber = cardNumber };
using (var db = new Entities())
{
db.Users.Attach(user);
db.Entry(user).Property(x => x.CardNumber).IsModified = true;
db.Configuration.ValidateOnSaveEnabled = false;
db.SaveChanges();
}

Here is a code example to update the card number and save it.
using (var db = new Entities())
{
User user = db.Users.Where(u => u.Id == userIdToBeUpdated).FirstOrDefault();
user.CardNumber = cardNumber;
db.SaveChanges();
}

Related

How to overwrite data in the database? [ASP.NET]

This code saves my data to the database. The app records the time spent on each day of the month.
They write to the database in SQL Server, using EF. The problem is just that I would like them to overwrite instead of writing more
Controller:
List<Karta_Model> objNextKartaModel = new List<Karta_Model>();
for (int i = 0; i < liczbaDni; i++)
{
var modelNext = new Karta_Model()
{
Login = userName,
Rok = numerRoku,
Miesiac = numerMiesiaca,
DzMiesiaca = modelKarta.Model1[i].DzMiesiaca.Value,
DzTygodnia = modelKarta.Model1[i].DzTygodnia,
Rozpoczecie = modelKarta.Model1[i].Rozpoczecie
....
};
objNextKartaModel.Add(modelNext);
await _ecpContext.Karta.AddRangeAsync(objNextKartaModel);
await _ecpContext.SaveChangesAsync();
}
Id in SQL Server is defined as:
[Id] [int] IDENTITY(1,1)
I came up with the idea to extract the first row ID from the previously saved database
var nrIdBase = _ecpContext.Karta
.FirstOrDefault(f => f.DzMiesiaca == 1 &&
f.Miesiac == numerMiesiaca &&
f.Rok == numerRoku &&
f.Login == userName).Id;
but I don't know how to use it.
I tried something like this:
for (int i = 0; i < liczbaDni; i++)
{
var modelNext = new Karta_Model()
{
Id = nrIdBase +i,
Login = userName,
Rok = numerRoku,
Miesiac = numerMiesiaca,
DzMiesiaca = modelKarta.Model1[i].DzMiesiaca.Value,
DzTygodnia = modelKarta.Model1[i].DzTygodnia,
Rozpoczecie = modelKarta.Model1[i].Rozpoczecie
....
};
}
but I get an error:
InvalidOperationException: The instance of entity type 'Karta_Model' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.
Does anyone have an idea how to do this?
How to overwrite saved data once?
In order to update an existing recording in a database, you need to have it's ID before the update operation.
Then you can do this:
var existingRecord = _ecpContext.Karta.FirstOrDefault(x => x.Id == theExistingId);
if (existingRecord != null) {
existingRecord.Login = "CHANGED";
await _ecpContext.SaveChangesAsync()
}
This call that you are using:
await _ecpContext.Karta.AddRangeAsync(objNextKartaModel);
Is only for adding new items to the database.
Following the idea in my comment above, one thing you can do is to delete the existing data in the table before adding the new ones.
List<Karta_Model> objNextKartaModel = new List<Karta_Model>();
for (int i = 0; i < liczbaDni; i++)
{
var modelNext = new Karta_Model()
{
Login = userName,
Rok = numerRoku,
Miesiac = numerMiesiaca,
DzMiesiaca = modelKarta.Model1[i].DzMiesiaca.Value,
DzTygodnia = modelKarta.Model1[i].DzTygodnia,
Rozpoczecie = modelKarta.Model1[i].Rozpoczecie
....
};
objNextKartaModel.Add(modelNext);
//Add logic to delete the existing data
foreach(var model in _ecpContext.Karta)
{
_ecpContext.Karta.Remove(model);
}
await _ecpContext.Karta.AddRangeAsync(objNextKartaModel);
await _ecpContext.SaveChangesAsync();//One SaveChanges call is enough to update the database
}

Enter new data in db (EF)

I have method in controller
It receive data from post request and write to table
Here is code
[ResponseType(typeof(TimeTable))]
public IHttpActionResult PostTimeTable(TimeTable timeTable)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (ModelState.IsValid)
{
DateTime dt = DateTime.Today;
TimeTable c = (from x in db.TimeTables
where x.Company == timeTable.Company && x.INN == timeTable.INN
select x).First();
c.StartPause = timeTable.StartPause;
c.StartDay = timeTable.StartDay;
c.EndPause = timeTable.EndPause;
c.EndDay = timeTable.EndDay;
db.SaveChanges();
}
db.TimeTables.Add(timeTable);
db.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = timeTable.Id }, timeTable);
}
But it works well when record with INN and Company already in db.
But if it not in database I need to create new entry.
How I need to modify this method?
You can use a flag (exisingCompanyFlag) for edit mode or add new mode like this
bool existingCompanyFlag = true;
TimeTable c = (from x in db.TimeTables
where x.Company == timeTable.Company && x.INN == timeTable.INN
select x).FirstOrDefult();
if (c == null)
{
existingCompanyFlag = false;
c = new TimeTable();
}
c.StartPause = timeTable.StartPause;
c.StartDay = timeTable.StartDay;
c.EndPause = timeTable.EndPause;
c.EndDay = timeTable.EndDay;
if (!existingCompanyFlag)
db.TimeTables.Add(c);
You need a separate branch in your code for the insert case.
if (ModelState.IsValid) {
if (addingNewRow) {
TimeTable tt = new TimeTable {
// Populate properties (except identity columns)
};
db.TimeTables.Add(tt);
} else {
// update
}
db.SaveChanges();
}
To link to other entities use one of:
Assign instances:
x.Company = theCompany;
or, assign the instance id
x.CompanyId = companyId;
(#1 is easier if you already have the other entity loaded or are creating it – EF will sort out the ids – while #2 saves loading the whole other entity.)

Update multiple columns in Entity Framework

I want to update multiple columns in Entity Framework. I now use this :
var user = new Relations { Id=1, Status = 1, Date = DateTime.Now, Notification = 0 };
db.Relations.Attach(user);
db.Entry(user).Property(x => x.Status).IsModified = true;
db.Entry(user).Property(x => x.Notification).IsModified = true;
db.Entry(user).Property(x => x.Date).IsModified = true;
db.Configuration.ValidateOnSaveEnabled = false;
db.SaveChanges();
Is there a better way to update columns without repeating the code db.Entry(user).Property several times ?
you can Use EntityState Like this:
var user=db.users.Find(userId);
user.name="new name";
user.age=txtAge.text;
user.address=txtAddress.text;
context.Entry(user).State=Entitystate.Modified;
I prefer use:
var existingUser = context.Set<User>().Where(u => u.Id == 1);
context.Entry(existingUser).CurrentValues.SetValues(user);
Or you can use a 3rd lib like GraphDiff.
Yo update an entity you don't need to do this:
// build your entity object with new values
var user = new Relations { Id=1, Status = 1, Date = DateTime.Now, Notification = 0 };
//attach as modified in one single step
db.Entry(user).State = EntityState.Modified;
//execute update
db.SaveChanges();
This assumes you are setting all entity fields and there isn't RowVersion field in your entity. Extra steps would be required to manage these other situations.
Try this,
using (var db = new YourDb())
{
try
{
db.Entry(user).State = EntityState.Modified;
}
catch (Exception)
{
return false;
}
db.SaveChanges();
return true;
}
When an item is fetched via the context it is
automatically tracked in that context unless you change the default behavior.
So you could simple do:
var txtInputAge = 18;
var txtAdrressLine1 = "Some cool place"
//fetch the user
var user = db.Users.Find(userId);
//change the properties
user.Name = "new cooler name";
user.Age = txtInputAge;
user.Address = txtAdrressLine1;
//call save changes
db.SaveChanges();
Update - Add would look like
//create new entry
User user = new User();
user.Name = "new cooler name";
user.Age = txtInputAge;
user.Address = txtAdrressLine1;
//add to context
db.Users.Add(user);
//call save changes
db.SaveChanges();
using (var dbcontext = new MyModel())
{
var matchedRecords = dbcontext.DummyTable.Where(e => e.code.Equals(entry.code) &&
e.isValid.Equals(true)).ToList();
matchedRecords.ForEach(e => e.isValid = false);
dbcontext.SaveChanges();
}

C# Create employee. Save to SQL Database using EF

I'm saving an employee to a SQL database. I'm saving Firstname, Lastname, Username and Password. How should I do this to prevent saving more than one identical username?
I've tried this:
private void CreateEmployee()
{
using (var db = new TidrapportDBEntities())
{
var user = (from p
in db.Login
where p.username != null
select p).ToList();
foreach (var vUser in user)
{
if (vUser.username == textBoxUsername.Text)
{
labelSuccessFail.Visible = true;
labelSuccessFail.Text = "Accountname already exist.";
break;
}
else
{
var userInfo = new Login();
var persInfo = new PersonalInformation();
persInfo.firstname = textBoxFirstname.Text;
persInfo.lastname = textBoxLastname.Text;
userInfo.username = textBoxUsername.Text;
userInfo.password = textBoxPassword.Text;
userInfo.employeeId = persInfo.employeeId;
db.Login.Add(userInfo);
db.PersonalInformation.Add(persInfo);
db.SaveChanges();
textBoxFirstname.Text = string.Empty;
textBoxLastname.Text = string.Empty;
textBoxUsername.Text = string.Empty;
textBoxPassword.Text = string.Empty;
labelSuccessFail.Visible = true;
labelSuccessFail.Text = "Successfully created account.";
}
}
}
}
Any tips what I can try?
Kind regards,
Kristian
You should have a unique constraint on the username field. Not sure if you're doing code first, model first or DB first in your EF, but you should be able to google how to get it set on your database using the right method. That will throw an exception if you try to save one, so that makes sure you can't have more than one.
You could also use LINQ statement to restrict the list of users to the user name you wish to create and then you're just down to checking a bool to see if a row is returned or not. That way you're not having to read the entire database table (which your "toList" is doing).
In your code example, you're getting all the users where they have a user name, you're then looping round them, but your conditional code only really works if the first one matches the user name you're trying to save, otherwise you are going to try and recreate a duplicate the second time around. So just to get your code working you could try:
private void CreateEmployee()
{
using (var db = new TidrapportDBEntities())
{
var user = (from p
in db.Login
where p.username != null
select p).ToList();
bool found = false;
foreach (var vUser in user)
{
if (vUser.username == textBoxUsername.Text)
{
found = true;
labelSuccessFail.Visible = true;
labelSuccessFail.Text = "Accountname already exist.";
break;
}
}
if(!found)
{
var userInfo = new Login();
var persInfo = new PersonalInformation();
persInfo.firstname = textBoxFirstname.Text;
persInfo.lastname = textBoxLastname.Text;
userInfo.username = textBoxUsername.Text;
userInfo.password = textBoxPassword.Text;
userInfo.employeeId = persInfo.employeeId;
db.Login.Add(userInfo);
db.PersonalInformation.Add(persInfo);
db.SaveChanges();

Insert data using Entity Framework model

I'm trying to insert some data in my database using Entity Framework model, but for some unknown reasons to me, it does nothing.
Am I missing something here?
using (var context = new DatabaseEntities())
{
var t = new test
{
ID = Guid.NewGuid(),
name = "blah",
};
context.AddTotest(t);
context.SaveChanges();
}
It should be:
context.TableName.Add(TableEntityInstance);
For versions of entity framework before 6, it was:
context.TableName.AddObject(TableEntityInstance);
Where:
TableName: the name of the table in the database.
TableEntityInstance: an instance of the table entity class.
If your table is Orders, then:
Order order = new Order();
context.Orders.Add(order);
For example:
var id = Guid.NewGuid();
// insert
using (var db = new EfContext("name=EfSample"))
{
var customers = db.Set<Customer>();
customers.Add( new Customer { CustomerId = id, Name = "John Doe" } );
db.SaveChanges();
}
Here is an example:
public void UpdatePlayerScreen(byte[] imageBytes, string installationKey)
{
var player = (from p in this.ObjectContext.Players where p.InstallationKey == installationKey select p).FirstOrDefault();
var current = (from d in this.ObjectContext.Screenshots where d.PlayerID == player.ID select d).FirstOrDefault();
if (current != null)
{
current.Screen = imageBytes;
current.Refreshed = DateTime.Now;
this.ObjectContext.SaveChanges();
}
else
{
Screenshot screenshot = new Screenshot();
screenshot.ID = Guid.NewGuid();
screenshot.Interval = 1000;
screenshot.IsTurnedOn = true;
screenshot.PlayerID = player.ID;
screenshot.Refreshed = DateTime.Now;
screenshot.Screen = imageBytes;
this.ObjectContext.Screenshots.Add(screenshot);
this.ObjectContext.SaveChanges();
}
}
var context = new DatabaseEntities();
var t = new test //Make sure you have a table called test in DB
{
ID = Guid.NewGuid(),
name = "blah",
};
context.test.Add(t);
context.SaveChanges();
Should do it
[HttpPost] // it use when you write logic on button click event
public ActionResult DemoInsert(EmployeeModel emp)
{
Employee emptbl = new Employee(); // make object of table
emptbl.EmpName = emp.EmpName;
emptbl.EmpAddress = emp.EmpAddress; // add if any field you want insert
dbc.Employees.Add(emptbl); // pass the table object
dbc.SaveChanges();
return View();
}

Categories