What is the equal code in EntityFramework to this sql code?
select Scope_Identity()
I want to get the id of the last record that i have inserted to database in EF.
You must ensure that your key property is mapped with StoreGeneratedPattern.Identity (here you can find some more about this setting). This should be used as default when generating the model from MS SQL database where the key column is defined with IDENTITY. After that it is enough to call SaveChanges on the context and the key property will be automatically filled for you.
Related
This is doing my head in. I have a pretty simple model class like this (generated by EF Core Power Tools):
In the Azure SQL database, I have the following foreign key relationship in place which associates a Sighting record with to every MachineLearningTaggedImage record:
ALTER TABLE [dbo].[MachineLearningTaggedImage] WITH CHECK
ADD CONSTRAINT [FK_MachineLearningTaggedImage_Sighting]
FOREIGN KEY([SightingId]) REFERENCES [dbo].[Sighting] ([SightingId])
GO
ALTER TABLE [dbo].[MachineLearningTaggedImage]
CHECK CONSTRAINT [FK_MachineLearningTaggedImage_Sighting]
GO
I am then trying to do a very run of the mill insert, with the SightingId value populated (because I want the newly inserted MachineLearningTaggedImage record to link to an existing Sighting record that already exists in the database):
var newImageTag = new MachineLearningTaggedImage
{
SightingId = sighting.SightingId
};
_db.MachineLearningTaggedImages.Add(newImageTag);
Save();
But the insert fails with the following error:
The MERGE statement conflicted with the FOREIGN KEY constraint "FK_MachineLearningTaggedImage_Sighting". The conflict occurred in database "MyDatabase", table "dbo.Sighting", column 'SightingId'.
I'm puzzled because my existing value of SightingId (3398670) definitely exists in the Sighting table as an existing record which I want to link to.
But for some reason, EF Core or SQL won't let me do this insert.
Now if I go directly into a SQL query window (outside of EF Core), I can successfully insert the new MachineLearningTaggedImage record with a SightingId value = 3398670 - no problem at all. It works..
What am I running into? Is it something related to me having only populated the SightingId value, but the actual Sighting child / related object property is still null when I attempt to insert? I thought you could simply populated an ID of a related object and EF Core would be happy with that.
I am using Oracle 11g database. Many tables created in database and indexer applied on Primary key. After that i used Entity Framework 5.0 to connect with database.
The issue is that , when i am saving any record in table, it doesn't send Primary key which is auto incremented value.
public HttpResponseMessage PostCategory(TBLCATEGORY tblcategory)
{
if (ModelState.IsValid)
{
db.TBLCATEGORies.Add(tblcategory);
db.SaveChanges();
int32 ID=tblcategory.ID;
return ID;
}
}
it returns ID =0;
And one more thing, while creating any column Integer in oracle, it is showing decimal in Entity Framework.
I am assuming that you have defined a sequence and a trigger in the Oracle database that does the auto increment of the ID column, so only the object in the EF model is not updated, but the actual entry in the database has the correct incremented ID value, right?
Then the problem is that the edmx model does not know that the column is actually an ID column where the value is generated in the database. You have to manually edit the edmx model. The respective column entry in the SSDL section must have the StoreGeneratedPattern property set to "Identity". This tells the model to check again the database after inserting to look up the generated ID value. However, everytime you update the model from the database, your manual changes are lost.
I have written a short blog post about it: http://blog.aitgmbh.de/2014/06/02/patch-for-entity-framework-models-based-on-oracle-databases/
And I have created a NuGet package that does everything for you whenever you build the project: http://bit.ly/1hbxIsO
This way, even after updating your edmx model, the Identity property is added again to the specified ID columns.
Could you check the following articles:
problem description:
http://connect.microsoft.com/VisualStudio/feedback/details/505178/storegeneratedpattern-property-in-ado-net-entity-model-designer-sets-cdsl-annotation-but-not-ssdl-attribute
solution to the problem:
http://visualstudiogallery.msdn.microsoft.com/a63745c0-a781-48fa-a7d2-573ee80b5d7e
Probably sounds like a silly question, but there is an aspect about it I would like to know:
I'm working with objects that have a Guid-property for PrimaryKeys, which gets auto-generated in the database. I am using Entity Framework, Code First. If I do a Console.WriteLine with this property before saving, the value is
00000000-0000-0000-0000-000000000000.
After using Add and SaveChanges in the context, if I do a Console.WriteLine again with the same property, I have a value:
615f98eb-4ced-422a-877f-b9caa6f2b91f
Obviously, the object in memory has been updates. But I want to know how. The Guid is genereated in the database, so what happens?
Does the Guid-property of the object simply get updated from the database through EF, or does EF reload the entire object into memory after saving it in the database?
I would like to know, because that will determine how I design NUnit-tests in the same project.
Your EF object is updated when you call domainContext.SaveChanges(); Your new Id is generated by SQL database and value of Id is return value from DB. It is same for data types int, Guid and similar.
EF does not only submit an Insert/Update statement, at the same time it does a get statement to retrieve the generated primary key. In fact it is one single query. Your entity's primary key is then updated with the retrieved one. No magic behind this.
That's also one of the reason why batch updates / inserts are not supported. Every entity has to be updated / inserted on its own.
This is a query that is being executed when inserting an entity with a computed int primary key:
insert [dbo].[TestTable]
([Name])
values ('myname' /* #0 */)
select [ID]
from [dbo].[TestTable]
where ##ROWCOUNT > 0
and [ID] = scope_identity()
As you can see, the insert statement is followed by a select statement retrieving the computed columns (in this case ID). If there are more computed columns they're all selected here.
Have a problem with incrementing.
I created a new object and tried set it into my DB I received an error of data violation. The index in table wasn't increased (Id=0).
Id - set as primary key in SQL table and the StoredGeneratedPattern property of field "Id" in EDM set as "Identity" so, obviously, it must be incremented automatically.
public void AddPhone(UserPhone phone)
{
context.AddToUserPhone(phone);
context.SaveChanges();
}
I can't understand why.
Entity Framework does not automatically increment IDs. That's the database's job. Set the ID column on the database table as an IDENTITY column so that it will auto-increment. Then you should find that after you SaveChanges() the phone's ID property will have been set to the value the database chose for it.
We are using Entity Framework 4.0 and we have an entity that is mapped to stored procedures provided by our DBA. The Insert, Update, and Delete functions in the mapping details all have their own stored procedures.
When using entities that are mapped to tables I am able to add a new entity, call dataContext.SaveChanges(); and then the new entity I instantiated automatically has its ID property populated with the value from the identity column in the database.
How can this be accomplished when the entity is mapped to stored procedures? Does the INSERT stored procedure have to do something special and/or do I have to do something special on dataContext.SaveChanges();?
Example
Traditional way
var newCustomer = new Customer
{
Name = "Fred",
Age = 24
};
// newCustomer.Id is null
dataContext.Customers.Add(newCustomer);
dataContext.SaveChanges()
// newCustomer.Id is what database identity column was set to.
Mapped to stored procedures.
var newCustomer = new Customer
{
Name = "Fred",
Age = 24
};
// newCustomer.Id is null
dataContext.Customers.Add(newCustomer);
dataContext.SaveChanges()
// newCustomer.Id is null
If you are using Identity column in database make sure that your stored procedure contains:
SELECT Scope_Identity() AS Id
after calling INSERT
Also make sure that PK in your entity mode is correctly configured with StoreGeneratedPattern set to Identity (should be automatically if you used Update from database)
I believe your DB needs to use ##identity or insert with a NewID() and return the Identity/NewID value back to you via the stored procedure. You technically could select from the database for the record you inserted, but that is a very questionable way to do it as; you don't know if the records was inserted (unless the SP failed at .Net), you may not know if duplicated records exists, or even if the data was changed after the insert but before the select. When in doubt I always highly recommend talking to your DBA about the best approach to your specific needs based your DBAs design.
Updates:
If he returns you the PK value, you should be able to do a standard select from the table to populate the entity like from e in context.entities where e.pkcolumn = spkeyreturned select e.
If he returns you ALL the data back, and can guarantee the data won't change, you might be able to create a new entity, populate it will all the data and use the Attach method. I personally wouldn't do that, but it is an option. Attaching and Detaching Object in Entity Framework.