Entity Framework DB First Identity Column override? - asp.net-mvc

I have a MVC-Project with a DB-First EDMX file from a production database.
Let's say table Person has an identity-column named ID.
I also have a copy of this database where I have turnd OFF the Identity-Option for the ID column. My goal is to synchronize data between these two databases.
To connect to each of these databases I use the same context-class with different connection-strings.
The problem with this is, that when I try to add a copy of a row from table Person from productionDB to my copyDB I get an error, because EntityFramework is trying to insert NULL for the ID column. I know that this is totally normal, because the EDMX-File has set identity to TRUE for the ID-column of table Person, but is there a way to programatically change this behaviour?
Context prod = new Context("ProductionConnectionString");
Context prodCopy = new Context("CopyConnectionString");
var prodEntity = prod.Person.First(); \\ RETURNS A PERSON WITH ID 1
prodCopy.Person.Add(prodEntity):
prodCopy.SaveChanges(); \\THIS WILL THROW AN EXCEPTION BECAUSE EF WILL REPLACE 1 WITH NULL BECAUSE IDENTITY OPTION
Any ideas?

Related

How to handle an autoincremented ID in HANA from a SAPUI5-application?

in my SAPUI5-Application I got the following function that takes the data and creates an entry in my HANA DB:
onCreateNewCustomer: function(){
var oEntry = {};
oEntry.NAME = this.byId("name").getValue();
oEntry.CITY = this.byId("city").getValue();
oEntry.PHONE = this.byId("phone").getValue();
oEntry.ID = this.byId("id").getValue();
// Post data to the server
this.getOwnerComponent().getModel("CustomerModel").create("/Customer", oEntry, null);
this.byId("createCustomer").close();
//location.reload();
}
The creating process works and my entries get saved. In the next step I wanted to implement my table in HANA in that way, that the ID of the entries will be autoincremented so the user does not have to enter it. I used the following command to create my table:
create column table TABLE
(ID bigint not null primary key generated by default as IDENTITY,
FIRSTNAME nvarchar(30))
That worked, table is created. The problem now is, if I use the code above without providing the ID, the following error is logged by the console:
The following problem occurred: HTTP request failed 400,Bad Request,The serialized resource has an missing value for member 'ID'.
The entry does not get saved in my DB. If I execute the following SQL-Statements in my HANA Workbench without providing the ID, it works:
insert into TABLE (FIRSTNAME) values (‘David’);
insert into TABLE (FIRSTNAME) values (‘Mike’);
insert into TABLE (FIRSTNAME) values (‘Bobby’);
So I did some searching on google but did not find a proper solution on how to do this. My goal is that the entry gets saved and the ID is provided by my HANA DB without providing it from my SAPUI5 Application.
Probably you are using ODataV2 XSODATA implementation which does not support auto-increment. The possible solution here is to use a database sequence and then with a separate request get a value from it and use it in OData create statement.
Did you try creating a new record by commenting out the below code like ?
oEntry.ID = this.byId("id").getValue();
With identity fields, if you provide the value you have to explicitly identify that you are providing the column value. Otherwise, just omit the columnn name and value from the INSERT command.

EF6 - Insert multiple entities and update last

I'm working with EF6 and I need to insert 2 entities and after update the last with some data of first.
This is an example:
var entity1 = new EntityT1();
setData(entity1);
var entity2 = new EntityT2();
setData(entity2);
ctx.Set<EntityT1>.Add(entity1);
ctx.Set<EntityT2>.Add(entity2);
ctx.SaveChanges();
//this is the result I would like
entity2.Prop1 = entity1.IdFromDb;
Can I make this in one step?
or...
I need to make two SaveChanges?
thanks
Can I make this in one step? or... I need to make two SaveChanges? thanks
You will need to do it in two SaveChanges. There is nothing that ensures you that entity 1 will be saved before entity 2 (unless they have some dependency) since the order you add your entity in the ChangeTracker doesn't matter.
If there is a relation between EntityT1 and EntityT2, I suggest you to use navigation property if that's the key but I don't think this is the scenario you are looking for.

Update part of primary key Entity Framework 4.0

I've a table with a compose primary key (3 columns):
UTP_ID (ITEMId)
UTS_ID (CategoryID)
USS_ID (SubCategoryID)
When I try to change SubCategory ,for example,with EF 4 i get follow error:
utl.USS_ID = Convert.ToInt32(ddlSubSetor.SelectedItem.Value);
the property is part of the object's key information and cannot be modified
Any Ideias?Why i can't change it?
EF implements an Identity Map between primary key property values and object references. It doesn't allow to change the key for the same object instance.
I would do this with direct SQL:
objectContext.ExecuteStoreCommand(
"UPDATE MyTable SET USS_ID = {0} WHERE UTP_ID = {1} AND UTS_ID = {2} AND USS_ID = {3}",
Convert.ToInt32(ddlSubSetor.SelectedItem.Value),
utl.UTP_ID, utl.UTS_ID, utl.USS_ID);
Make sure that your entity utl is detached from the context because this code directly writes into the database table and the entity doesn't get any information about this change. But this avoids having to delete and recreate the entity (which might be impossible due to existing foreign key constraints on the old row in the database).
As a result of being part of the entity key the object needs to be deleted from the context and re-attached with the new primary key value.
The Entity Framework works by having a context which manages the state of the entities, a collection of entities (basically the table) and the entity itself (a row of data). As data is read from the database it is added to the entity's collection which in turn is managed by the context for changes of state. Changing an Entity's key is really deleting the entry from the database and inserting a new one. As a result to change an entity key, first delete the entity from it's collection, detach the entity object to allow key modification, change the primary key value and re-attach the entity to the collection. Finally call save changes in the context to apply the changes to the database.
The following code should produce the desired results:
Context.UTLs.DeleteObject(utl);
Context.UTLs.Detach(utl);
Context.SaveChanges();
utl.USS_ID = Convert.ToInt32(ddlSubSetor.SelectedItem.Value);
Context.UTLs.AddObject(utl).
Context.SaveChanges();

Cannot insert new Employee entity using InsertOnSubmit()

I'm facing this exception An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported. when I try to insert a new entity into my Employees table (the master one).
There is a relationship between the master Employees table and the details Orders table, and I'm sure that the relationship between these two tables (and specifically Employee.Orders EntitySet) is the cause of the problem since when I removed the relationship, it returns back to insert into Employees table with no problems.
When I searched for the problem, there was this blog post which I tried to implement but my case is a different than the one in the blog post in these items:
He faces the exception when tries to update (while I try to insert).
The tables architecture is different.
how can I solve this problem?
Here's the insertion code:
Employee emp = new Employee();
emp.Name = empName; // empName is a local variable
// What should I default emp.Orders to?
dc.Employees.InsertOnSubmit(emp);
dc.SubmitChanges();
P.S: My DataContext is defined on class-level in my repository and the exception is being thrown when I call dc.SubmitChanges();. and I didn't Attach any object why does it say that?
Here is an article explaining what you need to do using the Attach and Detach methods:
http://www.codeproject.com/KB/linq/linq-to-sql-detach.aspx
I am guessing it is trying to save something else besides just the employee object or you aren't showing us the full code in your repository. When you instantiate your DataContext object (dc) try setting DeferredLoadingEnabled = false, and ObjectTrackingEnabled = false and see if it works. If it does, try watching the SQL code in SQL Server Profiler and see if it is modifying other objects that may have came from a different context like the message says.
var dc = new MyDataContext()
{
DeferredLoadingEnabled = false,
ObjectTrackingEnabled = false
};
My bet is on the primary key.
Are you sure the primary key is also set on auto increment?
Did you
try changing the name, does it work then?
What happens if you remove
all rows from your DB? can you insert one then?

Self referencing foreign key - GUID - Entity framework 4 insert problems

I have successfully used EF4 to insert rows automatically with a server generated GUID:
http://leedumond.com/blog/using-a-guid-as-an-entitykey-in-entity-framework-4/
Now how does one perform this task if there exists a RowID (guid) and ParentRowID (guid) with a primary-foreign key constraint between the two? What would I set .ParentRowID to?
NewCut = New Row With
{
.ParentRowID = .RowID
}
SaveChanges throws a fit every time.
The fact that the primary key is a GUID is in fact irrelevant because I attempted the same test using a standard autogenerated integer without success.
The solution is as simple as the one you have posted.
Just create both parent and child entities in code, do not set Entity Key and not forget to set StoreGeneratedPattern for all server-generated Guid columns.
Then perform either MasterEntityInstance.Children.Add(ChildEntityInstance), or ChildEntityInstance.MasterEntity = MasTerEntityInstance and call SaveChanges.
After the SaveChanges call both guid properties will be populated with the correct Guid values, and ChildEntity.MasterEntity Entity Key will be populated with the necessary MasterEntity Entity Key value.

Resources