Entitykey values cannot be changed once they are set - entity-framework

I have a method for editing a table (Human) in my database. That table is part of a 1 to many relationship. Human is on the many side.
Human has a foreign key named idOtherTable.
Now, here is how I'm trying to change it:
Employee e = (from x in db.Human
where x.idHuman == someNumber
select x).First();
e.name = name;
e.phoneNumber = phoneNumber;
//this is how I try to change it:
e.RoleReference.EntityKey.EntityKeyValues[0].Value = editEmployee.idRole;
but it says that once is set, the value cannot be changed. How can I resolve this?

Related

How to change the value of a tables attribute using LINQ/LAMBDA?

I have an order table and an orderStatus table, their relationship is as seen below:
I want to be able to change 'StatusID' to the value 2, of a specific order (i am able to get the specific order ID, and have loaded it into an integer variable) using a lambda expression within an action result - would there be any easy way of doing this?
So far i have tried:
//get specific order ID
int currentOrderId = newConfirmedOrderLine.OrderID;
//-----
Order statusChange = new Order();
statusChange.OrderStatus.StatusID = 2;
DBAccessor.SaveChanges();
I am new to linq and lambda, so any explanation with an answer would be greatly appreciated!
If DBAccessor is a DbContext then this could/should work. You need to load the Order entity that you want to change from the DBAccessor.Order DbSet, change it by setting a property, and then call SaveChanges.
var orderStatus = DBAccessor.OrderStatus.First(x => x.StatusID == 2);
var order = DBAccessor.Order.Find(currentOrderId);
order.OrderStatus = orderStatus;
DBAccessor.SaveChanges();

Saving Value into Relation Column

Im new to Caché and got a problem: I want to save a value into the Relation Column in Class B via Class A and thats not working ...
Currently I am doing it like this
In Class A:
set Obj1 = ##class(This.Is.Class.B).%New()
set Obj1.PID = ..id
set Obj1.PName = ..name
set status = Obj1.%Save(0)
Its saving the PName into Class B but not the PID which I defined as Relationship [One to Many] in Class B
Connection objects in a relationship are bidirectional. But in any case, you can't just set id to such property. You should set object or insert object depending on which side you want to do it. In your case you do it like
do obj1.PIDSetObjectId(..id)
To get more information read the documentation.

EF 5.0 DbSet Find method returns null

In the code below the value of item1 is null, while item2 is not null. Any ideas why Find method does not work properly in this case?
context= new EFModel.InputContext();
context.Items.Add(new Item{ Id = 1 });
var item1 = context.Items.Find(1);
var item2 = context.Items.Local.SingleOrDefault(i => i.Id == 1);
EDIT:
Thanks to #Maximc for pointing to the right direction. Apparently the issue was not the fact that the key was set to be auto generated and I assigned it. Somehow EF handles this situation properly by overwriting the aut generated Id with the user specified one. The problem was due to improper casting. My Id attribute is of type long so when I do var item1 = context.Items.Find((long)1); then it works.
Does the Id has the attribute [Key] ? I think this will be your issue.
EDIT:
After reading your comment, something you are saying here is false, you say Id is auto generated, (StoreGeneratedPattern="Identity") but then at the codeexample you use:
context.Items.Add(new Item{ Id = 1 });
Assiging a value to a Auto generated property will cause problems I think, anyway you shoudn t do that (Id = 1), just use:
context.Items.Add(new Item()); // the Id will be auto genereated since it has storeGeneratedPattern="Identity"
Then try to use Find again, also I think find will only work if there is only 1 item in the list, while if you force the Id (1) and there 2 Items with Id: 1 (Which I find strange, think there should be an error), then FirstOrDefault Will still work! (since it will just look for the first one and then return it. You should try, SingleOrDefault, here it will check if it found a item with that Id or there more then just 1, then it will return also null.
Hope you can solve it now :).

EF 5.0 set column equal to the default (computed) value of another column in one transaction

I have a table that has an Identity column and another column needs to have its value based on the computed identity column.
My EF code looks like this:
var context = new DBEntities();
var newTableRow = new TableRow();
newTableRow.Column1 = newTableRow.ComputedColumn;
context.TableRows.Add(newTableRow);
context.SaveChanges();
If ComputedColumn is an IDENTITY and Column1 is a nullable varchar(50) I would expect the value of Column1 to be the same as the ComputedColumn but it is null.
I have even tried this:
var context = new DBEntities();
var newTableRow = new TableRow();
context.TableRows.Add(newTableRow);
context.SaveChanges();
newTableRow.Column1 = newTableRow.ComputedColumn;
context.SaveChanges();
AND
var context = new DBEntities();
var newTableRow = new TableRow();
context.TableRows.Add(newTableRow);
context.SaveChanges();
var getTableRow = context.TableRows.Single(r => r.ComputedColumn == newTableRow.ComputedColumn);
getTableRow.Column1 = newTableRow.ComputedColumn.ToString();
context.SaveChanges();
Keep in mind that this is part of a larger transaction. What I don't want to do is complete the transaction then in a separate transaction do another update. I would like to keep everything in one transaction. This had been working in an insert proc before.
Thanks,
Brett
Your second an third example should work if ComputedColumn has DatabaseGeneratedOption.Identity. But they have separate transactions, which you don't want.
Your first example can't work. When a column has DatabaseGeneratedOption.Identity, EF reads the identity value back when executing SaveChanges. It is not aware of any special instruction you might have tried to convey with
newTableRow.Column1 = newTableRow.ComputedColumn;
As for EF, it's just an assignment with an empty value.
Maybe the best alternative is to add a computed column to your database table. You will kill two birds with one stone:
It is transactional, because the computed column just re-displays the identity column
You prevent redundancy and possible value conflicts.
I just reviewed the model and you're right there was a change I didn't notice. Column1 had been set as a computed value. Removing that value should fix the problem.

Entity Framework Foreign Key Queries

I have two tables in my entity framework, objects, and parameters which have a foreign key pointing to the object to which they belong. I want to populate a tree with all the attributes of a certain object. So in order to find those I want to do this:
String parentObject = "ParentObjectName";
var getAttributes = (from o in myDB.ATTRIBUTE
where o.PARENT_OBJECT == parentObject
select o);
However when I try to do this I get an error saying it cannot convert from type OBJECT to string, even though in the database this value is stored as a string. I have a workaround where I get an instance of the parentObject, then go through every attribute and check whether it's parent_object == parentObjectInstance, but this is much less efficient than just doing 1 query. Any help would be greatly appreciate, thanks!
Well, PARENT_OBJECT.ToString() can't be called (implicitly or explicitly) in L2E, but if it just returns a property, you can look at that directly:
String parentObject = "ParentObjectName";
var getAttributes = (from o in myDB.ATTRIBUTE
where o.PARENT_OBJECT.NAME == parentObject
select o);
...note the .NAME
Try this:
String parentObject = "ParentObjectName";
var getAttributes = (from o in myDB.ATTRIBUTE
where o.PARENT_OBJECT.ToString() == parentObject
select o);