I'm working with EF Core and I've encountered an issue when trying to add a new migration using this command:
dotnet ef migrations add mig_somename
My UpdateQueueStatus is a ValueObject and not an entity, but EF Core seems to be treating it as an entity and is expecting a primary key.
Here's the error message I get :
The entity type 'UpdateQueueStatus' requires a primary key to be defined.
If you intended to use a keyless entity type, call 'HasNoKey' in 'OnModelCreating'.
For more information on keyless entity types, see https://go.microsoft.com/fwlink/?linkid=2141943.
I've defined the UpdateQueueStatus as a ValueObject with a string conversion using a custom converter and comparer, but EF Core is still expecting a primary key.
Here's the relevant code snippet:
// Inside OnModelCreating
modelBuilder.Entity<UpdateQueueEntry>(builder =>
{
builder.HasKey(x => x.Id);
builder
.Property(x => x.Status)
.HasConversion<string>(new UpdateQueueStatusConverter(), new UpdateQueueStatusComparer());
});
public class UpdateQueueStatusConverter : ValueConverter<UpdateQueueStatus, string>
{
public UpdateQueueStatusConverter(ConverterMappingHints mappingHints = null) : base
(
v => v.Value,
v => new UpdateQueueStatus(v),
mappingHints
)
{
}
}
public class UpdateQueueStatusComparer : ValueComparer<UpdateQueueStatus>
{
public UpdateQueueStatusComparer() : base
(
equalsExpression: (c1, c2) => c1.Value == c2.Value,
hashCodeExpression: c => c.Value.GetHashCode(),
snapshotExpression: c => c.Value
)
{
}
}
// Entity and ValueObject definitions ...
public class UpdateQueueEntry : IEntity<int>, ICreationTimeTracked
{
private UpdateQueueEntry()
{
}
public int Id { get; set; }
public UpdateQueueStatus Status { get; set; }
}
public class UpdateQueueStatus
{
public static readonly UpdateQueueStatus None = new UpdateQueueStatus("None");
public static readonly UpdateQueueStatus Queued = new UpdateQueueStatus("Queued");
// more statuses...
public string Value { get; }
public UpdateQueueStatus(string value)
{
Value = value;
}
public UpdateQueueStatus()
{
}
// Removed for brevity: Implicit operators, equality, etc.
public static implicit operator string(UpdateQueueStatus status);
public static implicit operator UpdateQueueStatus(string value);
public override string ToString();
public static UpdateQueueStatus Parse(string value);
public static bool operator ==(UpdateQueueStatus left, UpdateQueueStatus right);
public static bool operator !=(UpdateQueueStatus left, UpdateQueueStatus right);
public bool Equals(UpdateQueueStatus? obj);
public override bool Equals(object? obj);
public override int GetHashCode();
}
I've omitted some parts of the UpdateQueueStatus class for brevity, such as implicit operators and equality members.
Can someone help me understand why EF Core is treating my ValueObject as an entity and how to resolve this migration error?
Edit: I noticed that modelBuilder._builder._entityTypes contains UpdateQueueStatus, even tho there is no DbSet of it.
Thanks @sa-es-ir:
modelBuilder.Ignore<UpdateQueueStatus>();solved the problem