I'm writing an ASP.NET Web API right now and everything works just fine for 2 controllers. Now I try to do exactly the same as before but this time I get a weird error:
System.InvalidOperationException: "The entity type 'UserItem' requires a primary key to be defined."
Well then, why does UserItem
needs a primary key when the others don't?
This is my UserItem
class:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace ModulApi.Models { public class UserItem { public int matrikelnr { get; set; } public string studiengang { get; set; } public string user_semester { get; set; } public string user_max_klausur { get; set; } //Not necessary Constructor. I try to fix the primary Key error. public UserItem() { this.matrikelnr = 0; this.studiengang = ""; this.user_max_klausur = ""; this.user_semester = ""; } } }
And my WORKING LoginItem
class:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace ModulApi.Models { public class LoginItem { public long Id { get; set; } public string username { get; set; } public string password { get; set; } public string matrikelnr { get; set; } public string email { get; set; } public string email_verified { get; set; } public LoginItem() { this.Id = 0; this.username = ""; this.password = ""; this.matrikelnr = ""; this.email = ""; this.email_verified = ""; } } }
As you see, I got getter and setter set up, so the error can't be there.
Here is where the error occurs:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using ModulApi.Models; using ModulApi.DBConnectors; // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 namespace ModulApi.Controllers { [Route("api/user")] public class UserController : Controller { private readonly UserContext _context; public UserController(UserContext context) { _context = context; if (_context.UserItems.Count() == 0) <--- Error right here { getDataFromConnector(_context); } } private void getDataFromConnector(UserContext context) { //Getting my Data from Database method } . .
Well Since it is in a Context call, I'll attach UserContext as well, but again it is the same as in LoginContext, which works just fine.
UserContext:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; namespace ModulApi.Models { public class UserContext : DbContext { public UserContext(DbContextOptions<UserContext> options) : base(options) { } public DbSet<UserItem> UserItems { get; set; } } }
Has anyone a clue why I get this weird error? And why all other Controllers work fine which do exactly the same?
The primary key is an attribute or a set of attributes that uniquely identify a specific instance of an entity. Every entity in the data model must have a primary key whose values uniquely identify instances of the entity.
An entity key is a property or a set of properties of an entity type that are used to determine identity. The properties that make up an entity key are chosen at design time. The values of entity key properties must uniquely identify an entity type instance within an entity set at run time.
Configuring a primary key By convention, a property named Id or <type name>Id will be configured as the primary key of an entity. Owned entity types use different rules to define keys. You can configure a single property to be the primary key of an entity as follows: Data Annotations.
Entity Framework Core supports composite keys - primary key values generated from two or more fields in the database. Composite keys are not covered by conventions or data annotation attributes. The only way to configure composite keys is to use the HasKey method.
Entity Framework goes by convention. That means that if you have an object with a property named Id
, it will assume that it is the Primary Key for the object. That's why your LoginItem
class works fine.
Your UserItem
class has no such property, and therefor it can't figure out what to use as the primary key.
To fix this, affix the KeyAttribute to whatever your primary key is on your class. For example:
// Need to add the following using as well at the top of the file: using System.ComponentModel.DataAnnotations; public class UserItem { [Key] public int matrikelnr { get; set; } public string studiengang { get; set; } public string user_semester { get; set; } public string user_max_klausur { get; set; } // ... }
Your working LoginItem
has:
public long Id { get; set; }
Properties called *id
are detected and used as the primary key by convention. You need to explicitly set the [Key]
attribute otherwise.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With