【发布时间】:2019-09-13 05:40:06
【问题描述】:
我在使用代码优先数据库迁移时遇到AspNetCore.Identity.EntityFrameworkCore 2.1.6 错误。错误是
实体类型“ModeratedUser”需要定义一个主键。
这让我很困惑,因为我使用 Fluent Api 为所有实体定义了一个主键。我已经对此特定问题进行了研究,并且我遇到的所有帖子都涉及不同的问题(请注意,我遵循以下定义我的多对多关系:https://www.learnentityframeworkcore.com/configuration/many-to-many-relationship-configuration)
这里是实体和实体类型配置:
public class ModeratedUser
{
public Guid ModeratedId { get; set; }
public virtual List<ModeratorModerated> ModeratorModerated { get; set; }
}
public class ModeratorUser
{
public Guid ModeratorId { get; set; }
public virtual List<ModeratorModerated> ModeratorModerated { get; set; }
}
//explicit class to outline many to many between moderated and moderators
public class ModeratorModerated
{
public Guid ModeratorId { get; set; }
public Guid ModeratedId { get; set; }
public ModeratedUser Moderated { get; set; }
public ModeratorUser Moderator { get; set; }
}
这里是实体类型配置:
public abstract class ModeratedConfiguration : EntityMappingConfiguration<ModeratedUser>
{
public override void MapToConfig(EntityTypeBuilder<ModeratedUser> builder)
{
builder.HasKey(x => x.ModeratedId);
builder.ToTable("ModeratedUsers", "Mod");
}
}
public abstract class ModeratorsConfiguration : EntityMappingConfiguration<ModeratorUser>
{
public override void MapToConfig(EntityTypeBuilder<ModeratorUser> builder)
{
builder.HasKey(x => x.ModeratorId);
builder.ToTable("ModeratorUsers", "Mod");
}
}
public abstract class ModeratorModeratedConfiguration : EntityMappingConfiguration<ModeratorModerated>
{
public override void MapToConfig(EntityTypeBuilder<ModeratorModerated> builder)
{
builder.HasKey(x => new { x.ModeratedId, x.ModeratorId });
builder.HasOne(x => x.Moderated)
.WithMany(x => x.ModeratorModerated)
.HasForeignKey(x => x.ModeratedId);
builder.HasOne(x => x.Moderator)
.WithMany(x => x.ModeratorModerated)
.HasForeignKey(x => x.ModeratorId);
builder.ToTable("ModeratorModerated", "Mod");
}
}
如您所见,我为 ModeratorUser.cs 和 ModeratedUser.cs 设置了 .HasKey,并为 ModeratorModerated.cs 配置类设置了 CompositeKey。
这是我的 Context 类:
public class DbContext : IdentityDbContext<ApplicationUser>
{
public DbContext(DbContextOptions<DbContext> options) : base(options)
{
}
public DbSet<CatalogItem> CatalogItems { get; set; }
public DbSet<ModeratedUser> ModeratedUsers { get; set; }
public DbSet<ModeratorUser> ModeratorUsers { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
builder.HasDefaultSchema("UDC");
builder.AddEntityConfigurationsFromAssembly(GetType().Assembly);
base.OnModelCreating(builder);
}
}
这是我用来实例化 EntityMappingConfigurations 的 ModelBuilderExtensions.cs 类...
public interface IEntityMappingConfiguration
{
void MapToConfig(ModelBuilder b);
}
public interface IEntityMappingConfiguration<T> : IEntityMappingConfiguration where T : class
{
void MapToConfig(EntityTypeBuilder<T> builder);
}
public abstract class EntityMappingConfiguration<T> : IEntityMappingConfiguration<T> where T : class
{
public abstract void MapToConfig(EntityTypeBuilder<T> b);
public void MapToConfig(ModelBuilder b)
{
MapToConfig(b.Entity<T>());
}
}
public static class ModelBuilderExtenions
{
private static IEnumerable<Type> GetMappingTypes(this Assembly assembly, Type mappingInterface)
{
return assembly.GetTypes().Where(x => !x.IsAbstract && x.GetInterfaces().Any(y => y.GetTypeInfo().IsGenericType && y.GetGenericTypeDefinition() == mappingInterface));
}
public static void AddEntityConfigurationsFromAssembly(this ModelBuilder modelBuilder, Assembly assembly)
{
var mappingTypes = assembly.GetMappingTypes(typeof(IEntityMappingConfiguration<>));
foreach (var config in mappingTypes.Select(Activator.CreateInstance).Cast<IEntityMappingConfiguration>())
{
config.MapToConfig(modelBuilder);
}
}
}
来自 VS2017 中 PackageManagerConsole 窗口的错误是:
System.InvalidOperationException:实体类型“ModeratedUser”需要定义主键。
如您所见,这是一个小型应用程序,但我无法通过使用 EFCore 的第一个 m-m。这在 EF6.2 中几乎没有那么具有挑战性。我在这里错过了什么?
【问题讨论】:
-
abstract 配置类 - 无法实例化,因此不会调用配置代码。
-
谢谢伊万。我添加了实例化抽象类的 ModelBuilderExtension 类。为了简洁起见,这种方法适用于我从 DBContext 类中删除的其他实体。出于某种未知原因,我正在专门与上面列出的实体作斗争。不错的收获。
标签: c# asp.net-core entity-framework-core database-migration