How to change primary key on a table using code first in entity framework - entity-framework-core

I have a table created by Entity Framework 6 Code first. It has the Id as a primary key. I would like to change this so that a guid property is the primary key instead. But I I keep getting this error "To change the IDENTITY property of a column, the column needs to be dropped and recreated". Can someone please show me what I need to do?

Related

Does Entity Framework Core have an option to use a default value of 0 instead of null for non existent references?

If I have an object called Project that has a property called Creator and creator is a complex type, EF will automatically use the value null if the Creator property has not been assigned. Is it possible to instead use 0 instead of null in the database fields?
No, that would break Foreign Key Constraints on the database side, since there wouldn't be a Creator row with a primary key of 0 for the Project row's foreign key to point to.
In a relational database, at least those that respect foreign key constraints, every relationship between rows is represented as a pair of primary, and foreign keys. The database is designed to enforce that a foreign key always points to a valid primary key. It will prevent you from updating a FK field to a value that doesn't exist in the PK field. It will also yell at you for trying to delete the row that contains the PK as long as the FK still points to it (unless cascade-delete is turned on, but that gets complicated).
In theory, Entity Framework could probably be forced in to trying to do what you want, but the database would reject it, and EF would almost certainly have issues trying to retrieve rows with the 0/null value in it if it is configured to include navigation properties.

How do you signify a primary key in EF Code First?

I am new to EF Code First. How do you go about representing that a variable in an object should be the primary key when it is peristed to a database table?
By default and by convention, if you have a column called ID or (EntityName)ID (e.g. CustomerID for an entity of type Customer), then that will be your primary key.
Otherwise, you need to use the [Key] attribute on another column.

Violation of PRIMARY KEY constraint on linked record when add a record using the entity framework

I have a table called farmers. Each farmer has a country specified that is mandatory.
When I add a new farmer to the database using antity framework, I get a violation on the country table. It looks like the entity framework wants to add the country to the country table, but I only want the guid in my farmer table:
Violation of PRIMARY KEY constraint 'PK_Country'. Cannot insert
duplicate key in object 'dbo.Country'. The statement has been
terminated.
Can somebody advise me on what I'm doing wrong? here the code for the insert:
newFarmer.Guid = Guid.NewGuid();
ents.Farmer.AddObject(newFarmer);
ents.SaveChanges();
return newFarmer;
I even checked the state of the country and it says unchanged.
One possible solution is that Entity Framework doesn't understand that your entity primary key is also the identity and should be auto-incremented. I had the same problem in an application using EF 4.1 with database first. To solve the problem, I had to::
Make sure my entities primary key had a name "ID" (to avoid putting a decorator [Key] above my Model class.
Make sure the property option "Identity" of your database system (SQL Server in my case) is set to "Yes".
Then, my EF4.1 was able to do the insert and update of my entities.
Hope this helps!

Entity Framework Is it possible to add an ASSOCIATION between Primary Keys and a Foreign Key

I've got the following entities on my EDMX :-
These two entites were generated by Update Model From Database.
Now, notice how my country has the following primary key :-
Name & IsoCode
this is because each country is UNIQUE in the system by Name and IsoCode.
Now, with my States ... it's similar. Primary Key is :-
Name & CountryId
Each state is unique by name and per country.
Now, the Foreign Key for States is a CountryId. This is the sql :-
ALTER TABLE [dbo].[States] WITH CHECK ADD
CONSTRAINT [FK_States_Countries] FOREIGN KEY([CountryId])
REFERENCES [dbo].[Countries] ([CountryId])
ON UPDATE CASCADE
GO
ALTER TABLE [dbo].[States] CHECK CONSTRAINT [FK_States_Countries]
GO
Pretty simple stuff.
BUT EntityFramework doesn't like it :( It's assuming that i need to connect some properties from State entity to both primary key properties in the Country entity.
Is it possible to add an ASSOCIATION between Country and State on Country.CountryId <-> State.CountryId ... like i have mapped in my DB ?
Cheers ;)
In EF (3.5 and 4.0) FKs MUST point to Primary Keys.
But you appear to be attempting to point to a Candidate Key (i.e. [Countries].[CountryId]
I know that this is something the EF team are considering for the next version though :)
Hope this helps
Alex
For proper DB normalization, first thing is that primary keys must be only CountryId and StateId fields - the main Id fields for each table.
And ss I see from the description Name & IsoCode and Name & CountryId should be actually Unique keys, not primary.
Then the model class State should have a field:
public Country Country { get; set; }
Now EF have very good examples and since 4.3.1 + it fully supports Code first / DB first models, which I think will ease solving this.
EF 5 have more compatibility updates so I think it wont be a problem for legacy DB engines.

SQLite with Entity Framework

I'm having a problem with primary keys in Entity Framework when using SQLite. SQLite wants an explicit NULL in the VALUES list on an autoincrementing primary key column. I haven't actually looked at the generated SQL in the EF Context, but I believe it's going with the usual SQL Server convention of providing no value for the autoincrementing column.
According to the site for the ADO.NET SQLite provider, EF is fully supported but I'm finding no help there. Is there a way to force EF to explicitly insert a NULL for the primary key value?
Well I've finally made this work :D. You need to set the id column as autoincrement, this way it does work with EF. Dont ask me why this isnt mentioned in the question about auto-increment in sqlite faq. This is an example:
create table Persona ( PersonaID integer primary key autoincrement, Nombre text)
Also, I didn't found a way to set this from within visual studio, I had to do it from the command line tool.
UPDATE: The following code works fine.
PruebaDBEntities data = new PruebaDBEntities();
foreach (int num in Enumerable.Range(1, 1000))
{
Persona p = new Persona() { Nombre = "Persona " + num, Edad = num };
data.AddToPersona(p);
data.SaveChanges();
Console.WriteLine(p.PersonaID);
}
The PersonaID wasn't set, and after the save operation it had the value asigned by sqlite.
Hooray... I've found the solution!
Declare the ID column as INTEGER PRIMARY KEY AUTOINCREMENT in your create table statement. INTEGER PRIMARY KEY won't work!
Update your Entity Framework Model in Visual Studio, set the ID column property StoreGeneratedPattern to "Computed"
You must set autoincrement to True. You can make this directly from VS by clicking ( Manage Indexes and Keys ) icon from the tool bar while you are in design table window, then update your Model.
I've had the same problem with EF and SQLite.
Try checking the second post:
http://sqlite.phxsoftware.com/forums/p/1418/6162.aspx
The cause for my problem was that the autoincrement was added to the database itself, but the entity model was not properly refreshed. So after the refresh, my field looked something like this:
<Property Name="ID" Type="integer" Nullable="false" StoreGeneratedPattern="Identity" />
(StoreGeneratedPattern="Identity" was added)
Before the refresh (with the old model), I just tried setting the id property to 0, which worked as well :)
From the book, "The Definitive Guide to SQLite" I read the following under primary key constraints:
"In reality, however, this column will simply be an alias for ROWID. They will all refer to the same value."
I believe that is the reason for needing to set AUTOINCREMENT in the column definition.
It seems EF provider for SQLite does not pick up the column as identity (autoincrement).
For database first, right click the column in EDMX designer and set the StoreGeneratedPattern to Identity.