I am very new To EntityFramework and having trouble to understand why first code doesn't update but second does. My aim is to update a record without querying db.
Is it too obvious?
using (CHATDBEntities db = new CHATDBEntities())
{
// update buddy
onlines buddy = new onlines();
buddy.id = 56;
buddy.last_seen = DateTime.Now;
buddy.status = (int)UserStatuses.Status.Chatting;
buddy.connected_to_id = 34;
buddy.room_id = 2;
db.SaveChanges();
}
using (CHATDBEntities db = new CHATDBEntities())
{
// update buddy
var buddy = db.onlines.First();
buddy.last_seen = DateTime.Now;
buddy.status = (int)UserStatuses.Status.Chatting;
buddy.connected_to_id = 34;
buddy.room_id = 2;
db.SaveChanges();
}
it looks like it is related to "id" which is primary identity key.
You have to retrieve an entity in order to update it, you can't just create a new one with the same id as a record from the database and expect EF to magically know that it needs to update the database. You could try attaching it to the ObjectContext but that is not how you are supposed to do updates.
Possibly you need to add your new buddy to onlines collection?
db.onlines.Add(buddy); // << this
db.SaveChanges();
The reason is because you need to select the object into the ObjectContect before you can update it. It looks like the only way to update the entity is to first read it.
Please see this other stackoverflow link which answers this.
Related
I am making a POST call to Add a flower to the database, but I want to update a record in another table if the if statement is true. If the statement is not true, it adds the flower without any problems but when I am trying to update PinkRoseId with a new id, it creates a new record instead of updating the old one.
Is there another way to update the database?
public void AddFlower(Flower flowerToAdd, int someId)
{
_flowerContext = _contextUtility.GetFlowerContext(flowerToAdd.FlowerName);
var pinkRoseId = _flowerService.GetFlowerIdByName(flowerToAdd.FlowerName, "PinkRose", "Rose");
if (flowerToAdd.SomeFlowerId.HasValue)
{
var flowerToUpdate = _updateService.UpdateFlowerBySomething(flowerToAdd.FlowerName, flowerToAdd.SomeFlowerId.Value, flowerToAdd.PetalAk);
flowerToUpdate.PinkRoseId = pinkRoseId;
_flowerContext.SaveChanges();
}
var firstId = _petalService.GetFlowerIdByName(flowerToAdd.FlowerName, "rose", "petal");
var secondId = _sunService.GetSunIdByTypeOf(flowerToAdd.FlowerName, flowerToAdd.SomeName, "sun");
flowerToAdd.FlowerId = secondId;
flowerToAdd.SomeOtherId = firstId;
flowerToAdd.CreatedDate = DateTime.UtcNow;
flowerToAdd.CreatedByUserID = someId;
_flowerContext.Flowers.Add(flowerToAdd);
_flowerContext.SaveChanges();
}
On reading more about Entity Framework, there is method AddOrUpdate which adds a new record or updates any existing records. Side note: I am using EF6 (not sure if AddOrUpdate is available in any older versions or not)
Solution 1
if (flowerToAdd.SomeFlowerId.HasValue)
{
var flowerToUpdate = _updateService.UpdateFlowerBySomething(flowerToAdd.FlowerName, flowerToAdd.SomeFlowerId.Value, flowerToAdd.PetalAk);
}
_flowerContext.Flower.AddOrUpdate(flowerToUpdate); -- this did the trick and updated the existing record instead of adding a new one
Using this method is highly discouraged as per my understanding as it can add new records. Yet to find another solution.
Solution 2
I figured out another way to get this done without using AddOrUpdate
var changeRequest = (from x in _flowerContext.FlowerUpdateSomething
where x.FlowerPrimaryId == flowerToUpdate.FlowerPrimaryId
select x).FirstOrDefault();
changeRequest.PinkRoseId = pinkRoseId;
_flowerContext.SaveChanges();
}
Update on Solution 2:
I copied the solution to another service (eg SunFlowerService) like the following:
public SomeDataBaseEntity UpdateFlower(int id)
{
var changeRequest = (from x in _flowerContext.FlowerUpdateSomething
where x.FlowerPrimaryId == id
select x).FirstOrDefault();
}
But now when I call this method like the following:
if (flowerToAdd.SomeFlowerId.HasValue)
{
var flowerToUpdate = _updateService.UpdateFlowerBySomething(flowerToAdd.FlowerName, flowerToAdd.SomeFlowerId.Value, flowerToAdd.PetalAk);
var update = _someOtherService.UpdateFlower(flowerToUpdate.Id);
update.PinkFlowerId = pinkFlowerId;
_flowerContext.SaveChanges();
}
It does not update the record in the database. I am not sure how to solve this problem, or why it would have such behavior. But on keeping the original LINQ query like the following:
var changeRequest = (from x in _flowerContext.FlowerUpdateSomething
where x.FlowerPrimaryId == flowerToUpdate.FlowerPrimaryId
select x).FirstOrDefault();
changeRequest.PinkRoseId = pinkRoseId;
_flowerContext.SaveChanges();
I am able to change the records in the database. Not sure why making another method doesn't work.
I am new to Dynamics CRM development. I want to batch update certain fields in Entity using Batch update method in Dynamics CRM Online.
I am using below code for performing batch update:
var multipleRequest = new ExecuteMultipleRequest()
{
Settings = new ExecuteMultipleSettings()
{
ContinueOnError = false,
ReturnResponses = true
},
Requests = new OrganizationRequestCollection()
};
foreach (var entity in entities.Entities)
{
UpdateRequest updateRequest = new UpdateRequest { Target = entity };
multipleRequest.Requests.Add(updateRequest);
}
ExecuteMultipleResponse multipleResponse = (ExecuteMultipleResponse)service.Execute(multipleRequest);
How can I specify only fields which I want to update instead of entire entity being updated?
Note: I have around 200,000 records to update using the above code. Currently it takes around 1.5 minute to update a single batch of 1000 records. So was thinking a way to update only required fields.
My recommended approach is to create a new Entity() object for the update. This way your update code doesn't need to worry about what fields were retrieved, it just takes the ones it cares about updating.
foreach (var entity in entities.Entities)
{
var newEntity = new Entity(entity.LogicalName, entity.Id);
//Populate whatever fields you want (this is just an example)
newEntity["new_somefield"] = entity.GetAttributeValue<string>("new_somefield").ToUpper();
UpdateRequest updateRequest = new UpdateRequest { Target = newEntity };
multipleRequest.Requests.Add(updateRequest);
}
You have to look at the way how the EntityCollection entities is filled up. If retrieving using RetrieveMultiple, then Pull the minimal fields may be the native Name field & PK Id field will come by default. This way not the whole entity will be updated back.
Avoid using AllColumns = true. Use ColumnSet to get minimal fields needed for validation.
ColumnSet = new ColumnSet("field_needed"),
Next, assign only the necessary fields like below inside loop.
foreach (var entity in entities.Entities)
{
UpdateRequest updateRequest = new UpdateRequest { Target = entity };
entity.Attributes["field_to_update"] = "field_value";
multipleRequest.Requests.Add(updateRequest);
}
My answer will help you to understand what went wrong & correcting it. Like Nicknow said, you can assign fresh entity to solve issue.
I use the Entity Framework and want to know the correct way to set a FK to a existing record.
Tables: Department<(1)----(n)>User
Here are my trys:
//here i want to add a new user to a existing department
using (EDModell.myEntities ctx = new EDModell.myEntities())
{
User uNew = new User();
uNew.FirstName = "Foo";
//1. try
uNew.DepartmentReference.EntityKey = new System.Data.EntityKey("myEntities.Department", "DepartmentID", 4);
//2. try
uNew.Department = ctx.Department.Single(x => x.DepartmentID == 4);
// add more data and save changes
}
The 1. try seems to be a bit insecure according to typos. It compiles without showing a error.
The 2nd requires a database select which isn't needed. In SQL a insert of the id is possible - so why not in entity framework?
Why can't I just set
uNew.DepartmentID = 4;
It is better to set it using the foreign key ID (2nd way), to avoid any issues regarding adding the foreign key entity to the database again
Assuming that all your navigation properties are set correctly, your Department DbSet, should have a Users collection. So setting the FK relationship would look like this:
using (EDModell.myEntities ctx = new EDModell.myEntities())
{
User uNew = new User();
uNew.FirstName = "Foo";
//get your department, either by FindById, Find, Where, Single, First ...
var department = ctx.Departments.Single(x => x.Id == 4);
department.Users.Add(uNew);
ctx.SaveChanges();
}
It's quite a simple question: When someone click on "Edit Plan" in my ASP.NET MVC project - He doesn't edit but create a new plan with. You can see it more clearly in my answer to my qeustion here: How do I duplicate an object?
Now I want to do the same thing to its references, and I did it like that:
var featurePlans = db.FeaturePlanBaseSet.Where(f => f.PlanId == plan.Id).ToList();
db.PlanSet.AddObject(plan);
db.SaveChanges();
for (var i = 0; i < featurePlans.Count(); i++ )
{
featurePlans[i].Plan = plan;
db.FeaturePlanBaseSet.AddObject(featurePlans[i]);
}
Plan is added when I do AddObject, but Feature isn't.
I get this error:
An object with the same key already exists in the ObjectStateManager.
The existing object is in the Unchanged state.
I'll be glad to know why does it happens.
It does not appear that you save after adding FeaturePlanBaseSet. You need to call db.SaveChanges() last to save all changes.
EDIT: It also appears that you are reading an existing FeaturePlanBaseSet record from the database and then adding that record back. The next line will retrieve an existing record.
var featurePlans = db.FeaturePlanBaseSet.Where(f => f.PlanId == plan.Id).ToList();
When you add featurePlans[i], you are adding the existing record. If you plan to add a new record, Do it as follows:
for (var i = 0; i < featurePlans.Count(); i++ )
{
var featurePlan = new FeaturePlanBaseSet();
featurePlan.Plan = plan;
...set other properties
db.FeaturePlanBaseSet.AddObject(featurePlan);
}
i have following trouble with LINQ to SQL entities:
// Context is DataContext that was auto genereted when i create my .dbml file
var cl = Context.Classes.ToArray();
var rm = Context.Rooms.ToArray();
List<DaySchedule> s = new List<DaySchedule>();
s.Add(new DaySchedule()
{
Class = cl[0],
DayOfWeek = 0,
Pair = 1,
Room = rm[0]
});
Context.SubmitChanges();
so, after "SubmitChanges" new DaySchedules will be saved to db. BUT i didn't call InsertOnSubmit function and i don't want to save this DaySchedule.
BTW,
if i will using following code:
s.Add(new Acceron.University.DBAccess.DaySchedule()
{
Class_id = cl[0].Class_ID,
DayOfWeek = 0,
Pair = 1,
Room_id = rm[0].Room_ID
});
It will not be auto saved to db.
Could you explain is it bug or feature and how i can solve it?
It is by design. Class and Room are context-aware entities, since they were queried against the context. Anytime a context-aware entity adds children, it queues up those changes automatically to the context and marks it as inserted. So you cannot add new entities without the auto-queuing feature. I'd highly recommend not calling save changes later on.