'The entity type 'Access' requires a primary key to be defined. If you intended to use a keyless entity type call 'HasNoKey()'
i have this ValueObject
:
public class Access : ValueObject<Access>
{
public string ControllName { get; set; }
public string ActionName { get; set; }
private Access()
{
}
public Access(string controllerName, string actionName)
{
ControllName = controllerName;
ActionName = actionName;
}
protected override IEnumerable<object> GetEqualityComponents()
{
yield return ControllName;
yield return ActionName;
}
}
and this is my ValueObject<Access>
:
public abstract class ValueObject<T>
where T : ValueObject<T>
{
protected abstract IEnumerable<object> GetEqualityComponents();
public override bool Equals(object obj)
{
var valueObject = obj as T;
if (ReferenceEquals(valueObject, null))
return false;
return IsEquals(valueObject);
}
private bool IsEquals(ValueObject<T> other)
{
return GetEqualityComponents().SequenceEqual(other.GetEqualityComponents());
}
public override int GetHashCode()
{
return GetEqualityComponents()
.Aggregate(1, (current, obj) => current * 23 + (obj?.GetHashCode() ?? 0));
}
public static bool operator ==(ValueObject<T> a, ValueObject<T> b)
{
if (ReferenceEquals(a, null) && ReferenceEquals(b, null))
return true;
if (ReferenceEquals(a, null) || ReferenceEquals(b, null))
return false;
return a.Equals(b);
}
public static bool operator !=(ValueObject<T> a, ValueObject<T> b)
{
return !(a == b);
}
}
and this is my DBContext :
public class StoreAdminPanelGetwayContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseSqlServer(@"Server=.; initial catalog=StoreAdminPanelGetway;integrated security=true");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsFromAssembly(typeof(Role).Assembly);
}
public DbSet<Role> Roles { get; set; }
public DbSet<AccessLevel> AccessLevels { get; set; }
}
this is my entity :
public class AccessLevel : Entity
{
public int RoleId { get; set; }
public Access Access { get; set; }
public Role Role { get; set; }
}
but when i need to add-migration initial
databse it show me this error :
The entity type 'Access' requires a primary key to be defined. If you intended to use a keyless entity type call 'HasNoKey()'.
but Access
is value object and it can not have an id . how can i solve this problem ???
Solution 1:[1]
EF Core has the concept of Owned Entity Types, which can be used to implement DDD value types.
In OnModelCreating
you would do the following:
modelBuilder.Entity<AccessLevel>().OwnsOne(x => x.Access);
This would store Access
objects in the same database table as AccessLevel
objects, and therefore requires no primary key.
Solution 2:[2]
If you are scaffolding a .net controller using a model and you get this error
The entity type 'Access' requires a primary key to be defined. If you intended to use a keyless entity type call 'HasNoKey()'
is because the model you are using in your command does not have and key property
By convention, a property named Id or Id will be configured as the primary key of an entity.
internal class Car
{
public string Id { get; set; } //this is the key
public string Make { get; set; }
public string Model { get; set; }
}
internal class Truck
{
public string TruckId { get; set; } //this is the key
public string Make { get; set; }
public string Model { get; set; }
}
When you primary key does not follow that convention you can use the [Key]
to indicate what propierty is you entity key
public class GameStats {
[Key]
public String playerName {set; get;}
public int gamesWon {set; get;}
}
If your entinty does not have keys you can use [KeyLess]
[Keyless]
public class BlogPostsCount
{
public string BlogName { get; set; }
public int PostCount { get; set; }
}
Taken from
Solution 3:[3]
If you want to save your value object in a different table, you can use a shadow property to define an ID that would exist in the database, but not in your model.
builder.Entity< Access >( a =>
{
a.Property< int >( "Id" );
a.HasKey( "Id" );
} );
Solution 4:[4]
I got the same error while creating a migration when one of my tables had no primary key but 2 Foreign Keys.
In your db context file, you will have to override OnModelCreating function and specify that the table has foreign keys.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Actor_Movie>().HasKey(am => new
{
am.ActorID,
am.MovieID
});
modelBuilder.Entity<Actor_Movie>().HasOne(m => m.Movie)
.WithMany(am => am.Actor_Movie).HasForeignKey(m => m.MovieID);
modelBuilder.Entity<Actor_Movie>().HasOne(a => a.Actor)
.WithMany(at => at.Actors_Movies).HasForeignKey(a => a.ActorID);
base.OnModelCreating(modelBuilder);
}
Note Here Table Actor_Movies is the table which has foreign key from Actor Table and Movies Table and both table has a list of Actor_Movies public List<Actor_Movie>? Actor_Movie { get; set; }
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Johnathan Barclay |
Solution 2 | Mauricio Gracia Gutierrez |
Solution 3 | Seb |
Solution 4 |