Cannot generate Id using Data annotation (EF6) - asp.net

I'm new at EF6 and Asp.net MVC5.
There's problem of generating a unique ID automatically when I try to create my entities using the code first approach.
Consider an entity like this:
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int PostId { get; set; }
[Required]
[MaxLength(100), MinLength(5)]
public string Title { get; set; }
public string Content { get; set; }
public string Thumbnail { get; set; }
public string Description { get; set; }
public DateTime DateCreated { get; set; }
When I put [DatabaseGenerated(DatabaseGeneratedOption.Identity)] on PostId or even remove it. I was always get an exception error like this:
“Cannot insert the value NULL into column ‘PostId'”.
“column does not allow nulls. INSERT fails.
I don't know why EF6's always try to insert a null value to the Id column.
Then later, I found a solution.
I changed
DatabaseGeneratedOption.Identity to DatabaseGeneratedOption.None
and the problem was solved.
However, this solution doesn't seem to work like I expected.
the values inserted to the column are always the same. It's not unique.
With EF core, everything is just simple, I don't need DatabaseGenerated,just leave it to convention. But with EF6, I'm stuck. What I want is the Id field must be unique and increase everytime it inserted to the database.
Can someone please help me this?

I'm new to EF also, but I just create an Id field and it is inserted automatically by SQL Server, such as this model in my current project. The Id field populates as expected when I add new rows:
public class BlogPosts
{
public int Id { get; set; }
[Required]
public string Title { get; set; }
[Required]
public string ShortPost { get; set; }
[Required]
public string Post { get; set; }
[Required]
public string Tags { get; set; }
[Required]
public DateTime Updated { get; set; }
}

When you apply DatabaseGeneratedOption.Identity to your key property you are telling EF that the database will generate the identity. From the error it sounds like your database PostId column is not configured as an identity or primary key.
If you manually created the table and columns in the database you should ensure the configuration is at least compatible, or you should use migrations to ensure the database is configured in a good state for your EF model.

Related

Entity Framework Core - optional foreign key

I am creating a web api that needs to return details about vehicles. The first part works fine, just returning data from my vehicles table. Now I have another table which may or may not contain additional data about vehicles in the first table. So when I get vehicle data, I want all of the vehicle data, and any additional data from the second table if it exists, like a left join in SQL.
Here are my classes (very much abridged for readability):
public class Vehicle
{
[Key]
[Required]
public string registrationNo { get; set; }
public string capacity{ get; set; }
public string maxGross{ get; set; }
}
public class VehicleDvlaDetail
{
[ForeignKey("Vehicle")]
public string? registrationNumber { get; set; }
public int? co2Emissions { get; set; }
}
And in my context class OnModelCreating I have (again, very abridged):
modelBuilder.Entity<Vehicle>(entity =>
{
entity.HasOne(dvlaRec => dvlaRec.dvlaDetail).WithMany().HasForeignKey(dvla => dvla.registrationNo);
});
This works fine when there is an associated record in the DVLA table, but that isn't always the case. I need to keep them as separate entities as my API will be required to return details from the DVLA table separately as well. Is there any way to create an optional foreign key, as clearly, what I am doing is wrong.
Friendly advice:
Primary key as a string is not a good practice because of performance issues when data table has lots of data in it.
It would be better if you create your model like this:
public class Vehicle
{
public long Id { get; set; }
public string RegistrationNo { get; set; }
public string Capacity { get; set; }
public string MaxGross { get; set; }
public List<VehicleDvlaDetail> VehicleDvlaDetails { get; set; }
}
public class VehicleDvlaDetail
{
public long? VehicleId { get; set; }
public int? Co2Emissions { get; set; }
public Vehicle Vehicle { get; set; }
}
Vehicle and VehicleDvlaDetail are now connected without additional code in OnModelCreating method and it is possible to fetch vehicles with details like this (this is assuming you have named properties in dbcontext Vehicles and VehicleDvlaDetails):
_dbContext.Vehicles.Include(x => x.VehicleDvlaDetails).ToList();
Also as foreign key VehicleId is nullable - this allows for vehicles not to have any dvla details.
Wow. I spent about 3 hours looking for the answer, just posted the question and came across this:
Create an optional foreign key using the fluid-API for Entity Framework 7
So simple...

EF Core - Identity field suddenly jumped by 1000 and not able to search with Id

I am having a problem with primary key/Id of one table in a project.
In this table, the Id suddenly jumped from 38 to 1039.
Now the real issue is, when i find the entity by 1039 it doesn't exists but finding it by 39 gives me the entity.
I am not sure about this behaviour and hence not able to find the solution.
My model
public class Domain : Entity
{
public string Name { get; set; }
public string Description { get; set; }
}
public abstract class Entity
{
public int Id { get; set; }
public DateTime InsertDate { get; set; }
public DateTime? UpdateDate { get; set; }
public DateTime? DeleteDate { get; set; }
public bool IsDeleted { get; set; }
}
Method is like this...
public async Task<Response> Delete(int id)
{
var domain = await DataContext.Domains.FindAsync(id);
if (domain == null)
{
return new Response(ResponseType.NotFound);
}
}
Can anyone please help ?
it depend from Database setting IDENTITY-CACHE.
Identity cache store some values of a identity columns in case of SQL CRASH during a transaction or similar.
To avoid gaps in an identity column, you need to set IDENTITY-CACHE to OFF running this command on a SQL query window:
ALTER DATABASE SCOPED CONFIGURATION SET IDENTITY_CACHE = OFF
GO
you will find more informations here:
https://social.technet.microsoft.com/wiki/contents/articles/40666.sql-server-2017-identity-cache-feature.aspx

Update Azure mobile app Asp.Net backend database

I have an Azure mobile app with an ASP.NET backend. I want to add a new column to an existing table. I have added the property and redeployed the service but this does not create the column in the table and gives me an error. I also tried to add the column manually with SQL management studio and kept the property in the DataObject class but this still errored. Please could you advise how I can add a new field to the mobile app database.
public class Petrol: EntityData
{
public int Mileage { get; set; }
public DateTime PurchaseDate { get; set; }
public float Quantity { get; set; }
public Decimal Cost { get; set; }
public string Station { get; set; }
public string Claim_Id { get; set; }
[ForeignKey("Claim_Id")]
public virtual Claim Claim { get; set; }
//This is the new column I would like to add
public string PhotoUrl { get; set; }
}
I have ran the Enable-Migrations command in Package Manager Console, but I am getting an error about the connection string.
The schema of your database is only deployed when your database is empty.
For a database already containing tables you have to implement code first migrations as described here: Implementing Table Controllers

Referencing the creator of a page blog (the connected user) in my entity

I have an entity for my accessing my pages (pages of a blog).
Here it is:
public class Page
{
[Key]
public int PageId { get; set; }
public string AuthorName { get; set; }
[ForeignKey("AuthorName")]
public virtual MembershipUser Author { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Content { get; set; }
public DateTime? PublishDate { get; set; }
public bool Published { get; set; }
public DateTime LastModified { get; set; }
}
As you can see, I would like to keep a reference to the person who created the page (in fact this is the connected user). So I defined an Author member in my class (of type MembershipUser). I also try to define the foreign key but it doesn't work because there is no primary key in the MembershipUser entity. I cannot add one to this entity because if is an aspnet object.
How can I proceed in order to have a reference to the creator of the page in my Page entity?
Thanks.
You can extend the MembershipUser by creating a CustomMembershipUser that will inherit from MembershipUser.
You can add any fields you want to your CustomMembershipUser, you will then also have to create a table of your own with both the original fields and your extra fields.
Here is some documentation that describes how you can do this.
What ORM are you using?
Anyway, you won't be able to reference a class that is not mapped in your ORM. You could create an entity like SystemUser, map it to a table and reference it at your Page entity. When you log in using Membership, you could query that SystemUser and store it in HttpSession so you can use it later.

EF Code First using non-Primary key to create one-to-many relationship

I have the following two entities:
public class User
{
public int PKID { get; set; }
public string Login { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public virtual ICollection<AppAccess> AppAccessList { get; set; }
}
public class AppAccess
{
public int PKID {get; set; }
public string Login { get; set; }
public string AppCode { get; set; }
}
The PKID field is the primary key and identity column of each table but the Login field is what links them in a one-to-many relationship where the User is the principal entity.
How can I setup the navigation property AppAccessList using the fluent API, if it is even possible, to use the Login field as the relationship key? BTW, the entities are based on existing schema that cannot be refactored at this time.
I don't believe this is possible out of the box, certainly not the ability to add a navigation property. I tried using the new power tools to reverse engineer a database and it just ignored the relationship, neither could i create it using code (annotations or fluent interface).
You can create the relationship using raw sql on the on OnModelCreating method to make the constraint, but you'd need to use join's manually to navigate between the tables.

Resources