我正在制作一个奇幻游戏应用程序。现在一个团队可以有多个玩家,但也有多个用户(比如联盟)。当我尝试将一个集合添加到团队表时,我收到以下错误 (见下文) 。 我试图在网上找到解决方案,似乎这个问题是由多对多的关系引起的。但是,我不知道这是怎么可能的。团队可以拥有许多用户,但用户只能拥有一个团队。 解决方案是创建一个连接表,但为什么我会在每个表上创建一个列以指向包含数据的连接表,当我可以让每个表上的列连接到另一个表时? 有谁知道是什么导致了这个错误以及如何修复它?
System.InvalidOperationException: Unable to determine the relationship represented by navigation property 'Team.Manager' of type 'User'. Either manually configure the relationship, or ignore this property from the model. at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.PropertyMappingValidationConvention.Apply(InternalModelBuilder modelBuilder)
at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnModelBuilt(InternalModelBuilder modelBuilder)
at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel()
at Microsoft.EntityFrameworkCore.Internal.LazyRef`1.get_Value()
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass16_0.<RealizeService>b__0(ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitTransient(TransientCallSite transientCallSite, ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitTransient(TransientCallSite transientCallSite, ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass16_0.<RealizeService>b__0(ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at Microsoft.EntityFrameworkCore.Design.MigrationsOperations.AddMigration(String name, String outputDir, String contextType)
at Microsoft.EntityFrameworkCore.Tools.Cli.MigrationsAddCommand.Execute(CommonOptions commonOptions, String name, String outputDir, String context, String environment, Action`1 reporter)
at Microsoft.EntityFrameworkCore.Tools.Cli.MigrationsAddCommand.<>c__DisplayClass0_0.<Configure>b__0()
at Microsoft.Extensions.CommandLineUtils.CommandLineApplication.Execute(String[] args)
at Microsoft.EntityFrameworkCore.Tools.Cli.Program.Main(String[] args)
Unable to determine the relationship represented by navigation property 'Team.Manager' of type 'User'. Either manually configure the relationship, or ignore this property from the model.
Team.cs
public class Team
{
[Key]
public int ID { get; set; }
public int ManagerID { get; set; }
public string Name { get; set; }
[ForeignKey("ManagerID")]
public virtual User Manager { get; set; }
public virtual ICollection<Player> Players { get; set; }
// Unable to determine the relationship represented by navigation property 'Team.Manager' of type 'User'
public virtual ICollection<User> TeamMebers { get; set; }
public Team()
{
TeamMebers = new List<User>();
Players = new List<Player>();
}
}
User.cs
public class User
{
[Key]
public int ID { get; set; }
public int? TeamID { get; set; }
public string UserName { get; set; }
public string Name { get; set; }
public bool ShowAsPm { get; set; }
public string Deactiviated { get; set; }
[ForeignKey("TeamID")]
public virtual Team Team { get; set; }
// How many hours they played
public virtual ICollection<Log> Hours { get; set; }
public User()
{
Hours = new List<Log>();
}
}
Log.cs
public class Log
{
[Key]
public int ID { get; set; }
public int? GameID { get; set; }
public int? ResultID { get; set; }
public int? UserID { get; set; }
public string SmNumber { get; set; }
public decimal? Duration { get; set; }
public DateTime LogDate { get; set; }
[ForeignKey("GameID")]
public virtual Game Game { get; set; }
[ForeignKey("ResultID")]
public virtual GameResult Result { get; set; }
[ForeignKey("UserID")]
public virtual User User { get; set; }
public Log() { }
}
Context.cs
protected override void OnModelCreating(ModelBuilder builder)
{
//builder.Entity<Team>().HasMany(t => t.TeamMebers).WithOne(u => u.Team).HasForeignKey(u => u.ID);
//builder.Entity<User>().HasOne(u => u.Team).WithMany(t => t.TeamMebers).HasForeignKey(t => t.ID);
builder.Entity<Team>().ToTable("Teams");
builder.Entity<User>().ToTable("Users");
builder.Entity<Log>().ToTable("Logs");
}
更新
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Team>().ToTable("Teams");
builder.Entity<User>().ToTable("Users");
builder.Entity<User>().HasOne(u => u.Team).WithMany(u => u.TeamMebers);
builder.Entity<Log>().ToTable("Logs");
}
例外
System.InvalidOperationException: The current CSharpHelper cannot scaffold literals of type 'System.Collections.Immutable.ImmutableSortedDictionary`2[System.Reflection.PropertyInfo,System.Type]'. Configure your services to use one that can. at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpHelper.UnknownLiteral(Object value)
at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.GenerateAnnotation(IAnnotation annotation, IndentedStringBuilder stringBuilder)
at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.GenerateEntityTypeAnnotations(IEntityType entityType, IndentedStringBuilder stringBuilder)
at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.GenerateEntityType(String builderName, IEntityType entityType, IndentedStringBuilder stringBuilder)
at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.GenerateEntityTypes(String builderName, IReadOnlyList`1 entityTypes, IndentedStringBuilder stringBuilder)
at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.Generate(String builderName, IModel model, IndentedStringBuilder stringBuilder)
at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGenerator.GenerateMetadata(String migrationNamespace, Type contextType, String migrationName, String migrationId, IModel targetModel)
at Microsoft.EntityFrameworkCore.Migrations.Design.MigrationsScaffolder.ScaffoldMigration(String migrationName, String rootNamespace, String subNamespace)
at Microsoft.EntityFrameworkCore.Design.MigrationsOperations.AddMigration(String name, String outputDir, String contextType)
at Microsoft.EntityFrameworkCore.Tools.Cli.MigrationsAddCommand.Execute(CommonOptions commonOptions, String name, String outputDir, String context, String environment, Action`1 reporter)
at Microsoft.EntityFrameworkCore.Tools.Cli.MigrationsAddCommand.<>c__DisplayClass0_0.<Configure>b__0()
at Microsoft.Extensions.CommandLineUtils.CommandLineApplication.Execute(String[] args)
at Microsoft.EntityFrameworkCore.Tools.Cli.Program.Main(String[] args)
The current CSharpHelper cannot scaffold literals of type 'System.Collections.Immutable.ImmutableSortedDictionary`2[System.Reflection.PropertyInfo,System.Type]'. Configure your services to use one that can.
答案 0 :(得分:6)
您遇到的例外情况解释了您的情况的“问题”:
Unable to determine the relationship represented by navigation property 'Team.Manager' of type 'User'. Either manually configure the relationship, or ignore this property from the model.
解决方案,正如消息所暗示的那样是手动定义这种关系。
builder.Entity<User>().HasOne(u => u.Team).WithMany(u => u.TeamMembers);
但是,这并不能完全解决您的问题,因为这并不能解决其中一个成员是管理员的问题。
更好的解决方案是使用以下中间类来处理关系,同时还将其中一个成员标记为Manager。这仍然无法解决每个团队单个管理员约束的问题,但它会更加接近。
public class TeamMember {
public int MemberId {get;set;}
public int TeamId {get;set;}
public bool IsManager {get;set;}
public virtual User Member {get;set;}
public virtual Team Team {get;set;}
}
//Either add an ID or use fluent API to define the key to be a combination of player/teamid