Closed drbergeron closed 2 years ago
Note that it will work without an error if you remove the BaseObjectAttribute class and have the OrderAttributeMap inherit directly from BaseSystemObject where the ID is, but this may not be the best solution in all cases where a more complicated inheritance is wanted.
Based on the exception, OrderAttributeMap
class has another entity type set as its base type. (We have updated the exception message, if you use nightly build then the exception message will indicate what is set as root type too). Looking at the CLR hierarchy, if any of BaseObjectAttribute
or BaseSystemObject
is added as an entity type in the model then it will be set as base type for OrderAttributeMap
. With the additional comment you made, it looks like BaseObjectAttribute
is added as entity type. If that is not intended then verify that it is not being added to the model through conventions or explicit configuration.
@drbergeron I took the code you have listed here and I wasn't able to reproduce the issue. As @smitpatel mentioned, the issue is probably because somewhere in your configuration you are doing something that is pulling BaseObjectAttribute
or BaseSystemObject
into the model. This could be that they are referenced from a navigation property in another type, or you are calling modelBuilder.Entity<T>()
on them at some point when doing configuration.
using Microsoft.Data.Entity;
using Microsoft.Data.Entity.Metadata.Builders;
using System;
namespace ConsoleApp1
{
public class Program
{
public static void Main(string[] args)
{
using (var db = new BloggingContext())
{
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
}
}
}
class BloggingContext : DbContext
{
public DbSet<OrderAttributeMap> OrderAttributeMaps { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Sample;Trusted_Connection=True;");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity(OrderAttributeMapConfiguration.GetConfiguration());
}
static class OrderAttributeMapConfiguration
{
public static Action<EntityTypeBuilder<OrderAttributeMap>> GetConfiguration()
{
Action<EntityTypeBuilder<OrderAttributeMap>> config = cm =>
{
cm.ToTable("OrderAttributeMaps");
cm.HasKey(c => c.Id);
cm.Property(c => c.AttributeRef);
cm.Property(c => c.Date);
cm.Property(c => c.AllowMultipleValues);
cm.Property(c => c.CreatedDate).IsRequired(true); ;
cm.Property(c => c.ModifiedDate).IsRequired(true);
cm.Property(c => c.Deleted).IsRequired(true);
};
return config;
}
}
}
public abstract class BaseSystemObject
{
public BaseSystemObject()
{
this.CreatedDate = DateTime.UtcNow;
this.ModifiedDate = DateTime.UtcNow;
}
public int Id { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime ModifiedDate { get; set; }
public bool Deleted { get; set; }
}
public class BaseObjectAttribute : BaseSystemObject
{
public bool AllowMultipleValues { get; set; }
}
public class OrderAttributeMap : BaseObjectAttribute
{
public int AttributeRef { get; set; }
public DateTime Date { get; set; }
}
}
I'm going to close this one out as I'm pretty confident that we've got to the bottom of this... but feel free to re-open if needed (please be sure to include a code listing to reproduce the issue).
@rowanmiller @smitpatel Thanks for the follow up. To confirm I did have the BaseObjectAttribute somewhere that was causing this error. I'll need to check TFS history and i'll update this issue a bit later with exactly what the call was. Thank you.
I Have an entity type that inherits from a class, that inherits from a class with an Id, similar to below:
I then have a class inheriting this with some properties for mapping:
And then I have the derived class that I want to map in EF:
DbContext looks as follows:
When this is executing I'm getting a runtime error with the following message: System.InvalidOperationException occurred HResult=-2146233079 Message=The derived type 'Models.OrderAttributeMap' cannot have keys other than those declared on the root type. Source=EntityFramework.Core StackTrace: at Microsoft.Data.Entity.Metadata.Internal.EntityType.AddKey(IReadOnlyList
1 properties) at Microsoft.Data.Entity.Metadata.Internal.InternalEntityTypeBuilder.<>c__DisplayClass14_0.<HasKey>b__1() at Microsoft.Data.Entity.Metadata.Internal.MetadataDictionary
2.GetOrAdd(Func1 getKey, Func
1 createKey, Func2 createValue, Func
2 onNewKeyAdded, ConfigurationSource configurationSource) at Microsoft.Data.Entity.Metadata.Internal.InternalEntityTypeBuilder.HasKey(IReadOnlyList1 properties, ConfigurationSource configurationSource) at Microsoft.Data.Entity.Metadata.Internal.InternalEntityTypeBuilder.PrimaryKey(IReadOnlyList
1 properties, ConfigurationSource configurationSource) at Microsoft.Data.Entity.Metadata.Internal.InternalEntityTypeBuilder.PrimaryKey(IReadOnlyList1 clrProperties, ConfigurationSource configurationSource) at Microsoft.Data.Entity.Metadata.Builders.EntityTypeBuilder
1.HasKey(Expression1 keyExpression) at Sql.Implementations.ModelBuilders.OrderAttributeMapConfiguration.<>c.<GetConfiguration>b__0_0(EntityTypeBuilder
1 cm) in C:\Programming\Solution-Dev\src\Sql.Implementations\ModelBuilders\Order\OrderAttributeMapConfiguration.cs:line 16 InnerException:Based on the code there is only an ID on the root (BaseSystemObject). Is there something i'm missing here? I've tried to use the .HasBaseType(); but i got another error about using shadow state Entities.
Let me know if I need to provide anything else