简体   繁体   English

实体类型的实体框架实例无法跟踪

[英]Entity Framework instance of entity type cannot be tracked

I have the following entities and context with Entity Framework Core 1.1: 我在Entity Framework Core 1.1中拥有以下实体和上下文:

public class Language {
  public String LanguageCode { get; set; }
  public virtual ICollection<LanguageI18N> LanguagesI18N { get; set; } = new List<LanguageI18N>();
}

public class LanguageI18N {
  public String LanguageCode { get; set; }
  public String TranslationCode { get; set; }
  public String Name { get; set; }        
  public virtual Language Language { get; set; }
}

public class Context : DbContext {

  public DbSet<Language> Languages { get; set; }
  public DbSet<LanguageI18N> LanguagesI18N { get; set; }

  public Context(DbContextOptions options) : base(options) { }

  protected override void OnModelCreating(ModelBuilder builder) {

    base.OnModelCreating(builder);

    builder.Entity<Language>(b => {
      b.ToTable("Languages");
      b.HasKey(x => x.LanguageCode);
      b.Property(x => x.LanguageCode).IsRequired(true).HasMaxLength(2).ValueGeneratedNever();        
    });

    builder.Entity<LanguageI18N>(b => {
      b.ToTable("LanguagesI18N");
      b.HasKey(x => new { x.LanguageCode, x.TranslationCode });      
      b.Property(x => x.LanguageCode).HasMaxLength(2).IsRequired(true);
      b.Property(x => x.TranslationCode).HasMaxLength(2).IsRequired(true);
      b.HasOne(x => x.Language).WithMany(x => x.LanguagesI18N).HasForeignKey(x => x.LanguageCode).IsRequired(true).OnDelete(DeleteBehavior.Restrict);
      b.HasOne(x => x.Language).WithMany(x => x.LanguagesI18N).HasForeignKey(x => x.TranslationCode).IsRequired(true).OnDelete(DeleteBehavior.Restrict);      
    });      

  }

}

Then I created a Language with translations for its names as follows: 然后,我创建了一种带有其名称翻译的语言,如下所示:

public class Program {

  public static void Main(String[] args) {

    DbContextOptionsBuilder builder = new DbContextOptionsBuilder<Context>();

    builder.UseInMemoryDatabase();

    using (Context context = new Context(builder.Options)) {

      Language language = new Language { LanguageCode = "en" };

      language.LanguagesI18N.Add(new LanguageI18N { LanguageCode = "en", TranslationCode = "en", Name = "English" });
      language.LanguagesI18N.Add(new LanguageI18N { LanguageCode = "en", TranslationCode = "pt", Name = "Inglês" });

      context.Languages.Add(language);

      context.SaveChanges();

    }         

  }

}

I am creating a language with code "en" and translations for its name in English and Portuguese. 我正在创建一种代码为“ en”并用英语和葡萄牙语翻译其名称的语言。

When I run the code I get the following error: 当我运行代码时,出现以下错误:

Unhandled Exception: System.InvalidOperationException: The instance of entity type 'LanguageI18N' cannot be tracked because another instance of this type with the same key is already being tracked. 未处理的异常:System.InvalidOperationException:无法跟踪实体类型'LanguageI18N'的实例,因为已经跟踪了具有相同键的该类型的另一个实例。 When adding new entities, for most key types a unique temporary key value will be created if no key is set (ie if the key property is assigned the default value for its type). 添加新实体时,对于大多数键类型,如果未设置任何键(即,如果为键属性分配了其类型的默认值),则将创建唯一的临时键值。 If you are explicitly setting key values for new entities, ensure they do not collide with existing entities or temporary values generated for other new entities. 如果您为新实体明确设置键值,请确保它们不与现有实体或为其他新实体生成的临时值冲突。
When attaching existing entities, ensure that only one entity instance with a given key value is attached to the context. 附加现有实体时,请确保仅将一个具有给定键值的实体实例附加到上下文。

What am I missing? 我想念什么?

UPDATE UPDATE

The code works with InMemoryDatabase and the change suggested by Ivan Stoev: 该代码适用于InMemoryDatabase和Ivan Stoev建议的更改:

b.HasOne<Language>().WithMany().HasForeignKey(x => x.TranslationCode).IsRequired(true).OnDelete(DeleteBehavior.Restrict);

But when I replaced InMemoryDatabase: 但是当我替换InMemoryDatabase时:

builder.UseInMemoryDatabase();

By SQL Server database: 通过SQL Server数据库:

  builder.UseSqlServer(yourConnectionString);

I get the following error: 我收到以下错误:

Unhandled Exception: Microsoft.EntityFrameworkCore.DbUpdateException: 
An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlClient.SqlException: 
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_LanguagesI18N_Languages_TranslationCode". 
The conflict occurred in database "TestDb", table "dbo.Languages", column 'LanguageCode'.
The statement has been terminated.

Any idea why? 知道为什么吗?

Here 这里

b.HasOne(x => x.Language).WithMany(x => x.LanguagesI18N).HasForeignKey(x => x.LanguageCode).IsRequired(true).OnDelete(DeleteBehavior.Restrict);
b.HasOne(x => x.Language).WithMany(x => x.LanguagesI18N).HasForeignKey(x => x.TranslationCode).IsRequired(true).OnDelete(DeleteBehavior.Restrict);      

you are trying to map one and the same association represented by the Language -> LanguagesI18N navigation properties to two different FKs ( LanguageCode and TranslationCode ), which is not possible. 您正在尝试将Language > LanguagesI18N导航属性表示的一个相同的关联映射到两个不同的FK( LanguageCodeTranslationCode ),这是不可能的。 The second line effectively overwrites the first, leading to incorrect setup. 第二行有效地覆盖了第一行,导致设置不正确。

Since you have two one-to-many relationships, and assuming the first line contains the correct setup for the first, the second can be setup by changing the last line to: 由于您有两个one-to-many关系,并且假设第一行包含第一行的正确设置,因此可以通过将最后一行更改为以下内容来设置第二行:

b.HasOne<Language>().WithMany().HasForeignKey(x => x.TranslationCode).IsRequired(true).OnDelete(DeleteBehavior.Restrict);

Such setup (w/o navigation property at both sides) was not possible in EF6, but perfectly supported in EF Core thanks to the parameterless overloads of the HasOne / HasMany methods. HasOne中无法进行这样的设置(两面都没有导航属性),但是由于HasOne / HasMany方法的无参数重载,因此在EF Core中得到了完美的支持。 Just keep them (as well as WithOne / WithMany ) in sync with your model navigation properties. 只需使它们(以及WithOne / WithMany )与模型导航属性保持同步即可。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法跟踪实体类型的实例 - The instance of entity type cannot be tracked 实体类型“”的实例无法跟踪 - The instance of entity type '' cannot be tracked 实体框架核心 - 无法跟踪实体类型的实例,因为已在跟踪具有键值的另一个实例 - Entity framework Core - The instance of entity type cannot be tracked because another instance with the key value is already being tracked 实体框架:无法跟踪类型 x 的实体,因为已跟踪具有相同键的另一个实例 - Entity Framework: Entity of type x cannot be tracked because another instance with same key is already being tracked 实体框架核心 - 无法跟踪实体类型的实例,因为已在跟踪具有相同键的此类型的另一个实例 - Entity Framework core - The instance of entity type cannot be tracked because another instance of this type with the same key is already being tracked Entity framework core 无法跟踪实体类型的实例,因为另一个实例具有相同的键值 - Entity framework core The instance of entity type cannot be tracked because another instance with the same key value Entity Framework Core:无法跟踪实体类型的实例,因为另一个实例具有相同的键值 - Entity Framework Core : instance of entity type cannot be tracked because another instance with same key value HostedService:无法跟踪实体类型的实例 - HostedService: The instance of entity type cannot be tracked 即使使用 AsNoTracking 也无法跟踪实体类型的实例 - The instance of entity type cannot be tracked even with AsNoTracking InvalidOperationException:无法跟踪实体类型&#39;ApplicationUser&#39;的实例 - InvalidOperationException: The instance of entity type 'ApplicationUser' cannot be tracked
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM