【问题标题】:EF - Unable to determine the relationshipEF - 无法确定关系
【发布时间】:2017-09-30 02:02:04
【问题描述】:

我正在制作一个奇幻游戏应用程序。现在一个团队可以有多个球员,但也可以有多个用户(如联赛)。当我尝试将集合添加到团队表时,我收到以下错误(见下文)。 我试图在网上找到解决方案,似乎这个问题是由多对多关系引起的。但是,我不明白这是怎么可能的。一个团队可以有很多用户,但一个用户只能有一个团队。 解决方案是创建一个连接表,但是为什么我要在每个表上创建一个列来指向一个包含数据的连接表,而我可以让每个表上的列连接到另一个表? 有谁知道是什么导致了这个错误以及如何解决它?

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. 

团队.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>();
    }
}

用户.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() { }
}

上下文.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. 

【问题讨论】:

    标签: c# sql-server entity-framework asp.net-core


    【解决方案1】:

    您遇到的异常中解释了您遇到的“问题”:

    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);
    

    但这并不能完全解决您的问题,因为这并不能解决其中一名成员是经理的问题。

    更好的解决方案是使用以下中间类来处理关系,同时还将其中一个成员标记为经理。这仍然不能解决每个团队的单一经理约束问题,但它更接近了。

    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
    

    【讨论】:

    • 玩家是你可以扮演的角色。为什么我要给玩家定义一个关系,他们和用户没有关系?
    • 我的错。应该是 TeamMembers,而不是 Players。编辑答案以匹配此
    • 请查看更新后的问题。我在尝试定义关系时出错。
    • 当您(临时)删除 Team 中的 ManagerId 和 Manager 变量时,它是否有效?我认为这可能会导致 EF 在理解您的类时遇到问题(因为同一个表的多个外键 - 用户)
    • 不幸的是,这不起作用,我仍然需要那个专栏。但是,我发现这里谈到的问题。 github.com/aspnet/EntityFramework/issues/6520。问题是我正在使用 EF Core,所以我不能使用该选项。当我弄清楚这一点时,我会及时通知你。感谢帮助的朋友。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-22
    • 2020-02-11
    • 1970-01-01
    • 2021-04-03
    • 1970-01-01
    相关资源
    最近更新 更多