播种数据库时无法跟踪实体类型 'Assignment' 的实例
The Instance of Entity Type 'Assignment' Cannot Be Tracked While Seeding Database
我是 Entity Framework Core 的新手,在为 mssql 数据库做种时遇到了问题。我有一个主题模型和一个具有一对多关系的分配模型(主题有一个 ICollection)。
我尝试添加:
storeContext.Entry<Subject>(subject1).State = EntityState.Detached;
为数据库创建的所有对象,但它仍然给出相同的错误。
我在尝试 运行 asp.net 核心应用程序时遇到此错误:
Exception thrown: 'System.InvalidOperationException' in Microsoft.EntityFrameworkCore.dll
An exception of type 'System.InvalidOperationException' occurred in Microsoft.EntityFrameworkCore.dll but was not handled in user code
The instance of entity type 'Assignment' cannot be tracked because another instance with the same key value for {'AssignmentId'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.
DatabaseInitializer class:
using FoxAcademicManager.Backend.Models;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
namespace FoxAcademicManager.Backend.Data
{
public class DatabaseInitializer
{
public static void Initialize(IServiceProvider serviceProvider)
{
using (var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<AcademicManagerContext>();
//do your stuff....
context.Database.EnsureCreated();
if (context.Subjects.Any()) return;
if (context.Events.Any()) return;
var subject1 = new Subject
{
SubjectId = 1,
Title = "Physics",
Description = "The AB Physics course",
GradeEarned = null,
GradeOverall = null,
};
var subject2 = new Subject
{
SubjectId = 2,
Title = "Chemistry",
Description = "A AB Chem course",
GradeEarned = null,
GradeOverall = null,
};
var assignment1 = new Assignment
{
Date = new DateTime(2020, 3, 1, 9, 0, 0),
Name = "Assignment 1",
Description = "Forces and Newton's Laws of Motion",
Score = 80,
Weight = 0.2,
AssignmentId = 1,
SubjectId = 1
};
var assignment2 = new Assignment
{
Date = new DateTime(2020, 3, 1, 9, 0, 0),
Name = "Assignment 2",
Description = "Gravity",
Score = 90,
Weight = 0.2,
AssignmentId = 2,
SubjectId = 1
};
var assignment3 = new Assignment
{
Date = new DateTime(2020, 3, 1, 9, 0, 0),
Name = "Assignment 3",
Description = "Frequency",
Score = 70,
Weight = 0.2,
AssignmentId = 3,
SubjectId = 1
};
var exam1 = new Assignment
{
Date = new DateTime(2020, 5, 1, 10, 0, 0),
Name = "Exam 1",
Description = "The first exam",
Score = 85,
Weight = 0.6,
AssignmentId = 1,
SubjectId = 2
};
var exam2 = new Assignment
{
Date = new DateTime(2020, 6, 1, 11, 0, 0),
Name = "Exam 2",
Description = "The second exam",
Score = 75,
Weight = 0.6,
AssignmentId = 2,
SubjectId = 2
};
var assignmentz1 = new Assignment
{
Date = new DateTime(2020, 5, 11, 12, 0, 0),
Name = "Assignment 1",
Description = "The first Chem grade",
Score = 85,
Weight = 0.2,
AssignmentId = 3,
SubjectId = 2
};
context.Subjects.AddRange(new Subject[] { subject1, subject2 });
subject1.Assignments = new List<Assignment> { assignment1, assignment2, assignment3 };
subject2.Assignments = new List<Assignment> { exam1, exam2, assignmentz1 };
context.UpdateRange(subject1, subject2);
context.SaveChanges();
}
}
}
}
这是 Startup.cs 文件:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Swashbuckle.AspNetCore.Swagger;
using FoxAcademicManager.Backend.Data;
using Microsoft.EntityFrameworkCore;
namespace FoxAcademicManager.Backend
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
var connection = Configuration.GetConnectionString("DefaultConnection");
services.AddDbContext<AcademicManagerContext>
(options => options.UseSqlServer(connection));
services.AddSwaggerGen(options =>
options.SwaggerDoc("v1", new Info { Title = "Academic Manager", Version = "v1"})
);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseSwagger();
if(env.IsDevelopment() || env.IsStaging())
{
app.UseSwaggerUI(options =>
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Academic Manager v1")
);
}
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseMvc();
DatabaseInitializer.Initialize(app.ApplicationServices);
}
}
}
使用EF Context初始化数据库,不能直接设置entity的key,它是自动生成的。
尝试使用以下代码进行测试:
型号Subject
public class Subject
{
public int SubjectId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string GradeEarned { get; set; }
public string GradeOverall { get; set; }
public List<Assignment> Assignments { get; set; }
}
型号Assignment
public class Assignment
{
public DateTime Date { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int Score { get; set; }
public double Weight { get; set; }
public int AssignmentId { get; set; }
public int SubjectId { get; set; }
public virtual Subject Subject { get; set; }
}
种子数据库
public static void Initialize(IServiceProvider serviceProvider)
{
using (var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
//do your stuff....
context.Database.EnsureCreated();
var subject1 = new Subject
{
Title = "Physics",
Description = "The AB Physics course",
GradeEarned = null,
GradeOverall = null,
};
var subject2 = new Subject
{
Title = "Chemistry",
Description = "A AB Chem course",
GradeEarned = null,
GradeOverall = null,
};
var assignment1 = new Assignment
{
Date = new DateTime(2020, 3, 1, 9, 0, 0),
Name = "Assignment 1",
Description = "Forces and Newton's Laws of Motion",
Score = 80,
Weight = 0.2,
Subject = subject1
};
var assignment2 = new Assignment
{
Date = new DateTime(2020, 3, 1, 9, 0, 0),
Name = "Assignment 2",
Description = "Gravity",
Score = 90,
Weight = 0.2,
Subject = subject1
};
var assignment3 = new Assignment
{
Date = new DateTime(2020, 3, 1, 9, 0, 0),
Name = "Assignment 3",
Description = "Frequency",
Score = 70,
Weight = 0.2,
Subject = subject1
};
var exam1 = new Assignment
{
Date = new DateTime(2020, 5, 1, 10, 0, 0),
Name = "Exam 1",
Description = "The first exam",
Score = 85,
Weight = 0.6,
Subject = subject2
};
var exam2 = new Assignment
{
Date = new DateTime(2020, 6, 1, 11, 0, 0),
Name = "Exam 2",
Description = "The second exam",
Score = 75,
Weight = 0.6,
Subject = subject2
};
var assignmentz1 = new Assignment
{
Date = new DateTime(2020, 5, 11, 12, 0, 0),
Name = "Assignment 1",
Description = "The first Chem grade",
Score = 85,
Weight = 0.2,
Subject = subject2
};
context.Subjects.AddRange(new Subject[] { subject1, subject2 });
context.Assignments.AddRange(new Assignment[] { assignment1, assignment2, assignment3, exam1, exam2 });
context.SaveChanges();
}
}
如果你坚持要插入id
的值,你可以尝试modelBuilder.Entity<Post>().HasData
,你可以参考Data Seeding
我是 Entity Framework Core 的新手,在为 mssql 数据库做种时遇到了问题。我有一个主题模型和一个具有一对多关系的分配模型(主题有一个 ICollection)。
我尝试添加:
storeContext.Entry<Subject>(subject1).State = EntityState.Detached;
为数据库创建的所有对象,但它仍然给出相同的错误。
我在尝试 运行 asp.net 核心应用程序时遇到此错误:
Exception thrown: 'System.InvalidOperationException' in Microsoft.EntityFrameworkCore.dll
An exception of type 'System.InvalidOperationException' occurred in Microsoft.EntityFrameworkCore.dll but was not handled in user code
The instance of entity type 'Assignment' cannot be tracked because another instance with the same key value for {'AssignmentId'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.
DatabaseInitializer class:
using FoxAcademicManager.Backend.Models;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
namespace FoxAcademicManager.Backend.Data
{
public class DatabaseInitializer
{
public static void Initialize(IServiceProvider serviceProvider)
{
using (var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<AcademicManagerContext>();
//do your stuff....
context.Database.EnsureCreated();
if (context.Subjects.Any()) return;
if (context.Events.Any()) return;
var subject1 = new Subject
{
SubjectId = 1,
Title = "Physics",
Description = "The AB Physics course",
GradeEarned = null,
GradeOverall = null,
};
var subject2 = new Subject
{
SubjectId = 2,
Title = "Chemistry",
Description = "A AB Chem course",
GradeEarned = null,
GradeOverall = null,
};
var assignment1 = new Assignment
{
Date = new DateTime(2020, 3, 1, 9, 0, 0),
Name = "Assignment 1",
Description = "Forces and Newton's Laws of Motion",
Score = 80,
Weight = 0.2,
AssignmentId = 1,
SubjectId = 1
};
var assignment2 = new Assignment
{
Date = new DateTime(2020, 3, 1, 9, 0, 0),
Name = "Assignment 2",
Description = "Gravity",
Score = 90,
Weight = 0.2,
AssignmentId = 2,
SubjectId = 1
};
var assignment3 = new Assignment
{
Date = new DateTime(2020, 3, 1, 9, 0, 0),
Name = "Assignment 3",
Description = "Frequency",
Score = 70,
Weight = 0.2,
AssignmentId = 3,
SubjectId = 1
};
var exam1 = new Assignment
{
Date = new DateTime(2020, 5, 1, 10, 0, 0),
Name = "Exam 1",
Description = "The first exam",
Score = 85,
Weight = 0.6,
AssignmentId = 1,
SubjectId = 2
};
var exam2 = new Assignment
{
Date = new DateTime(2020, 6, 1, 11, 0, 0),
Name = "Exam 2",
Description = "The second exam",
Score = 75,
Weight = 0.6,
AssignmentId = 2,
SubjectId = 2
};
var assignmentz1 = new Assignment
{
Date = new DateTime(2020, 5, 11, 12, 0, 0),
Name = "Assignment 1",
Description = "The first Chem grade",
Score = 85,
Weight = 0.2,
AssignmentId = 3,
SubjectId = 2
};
context.Subjects.AddRange(new Subject[] { subject1, subject2 });
subject1.Assignments = new List<Assignment> { assignment1, assignment2, assignment3 };
subject2.Assignments = new List<Assignment> { exam1, exam2, assignmentz1 };
context.UpdateRange(subject1, subject2);
context.SaveChanges();
}
}
}
}
这是 Startup.cs 文件:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Swashbuckle.AspNetCore.Swagger;
using FoxAcademicManager.Backend.Data;
using Microsoft.EntityFrameworkCore;
namespace FoxAcademicManager.Backend
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
var connection = Configuration.GetConnectionString("DefaultConnection");
services.AddDbContext<AcademicManagerContext>
(options => options.UseSqlServer(connection));
services.AddSwaggerGen(options =>
options.SwaggerDoc("v1", new Info { Title = "Academic Manager", Version = "v1"})
);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseSwagger();
if(env.IsDevelopment() || env.IsStaging())
{
app.UseSwaggerUI(options =>
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Academic Manager v1")
);
}
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseMvc();
DatabaseInitializer.Initialize(app.ApplicationServices);
}
}
}
使用EF Context初始化数据库,不能直接设置entity的key,它是自动生成的。
尝试使用以下代码进行测试:
型号
Subject
public class Subject { public int SubjectId { get; set; } public string Title { get; set; } public string Description { get; set; } public string GradeEarned { get; set; } public string GradeOverall { get; set; } public List<Assignment> Assignments { get; set; } }
型号
Assignment
public class Assignment { public DateTime Date { get; set; } public string Name { get; set; } public string Description { get; set; } public int Score { get; set; } public double Weight { get; set; } public int AssignmentId { get; set; } public int SubjectId { get; set; } public virtual Subject Subject { get; set; } }
种子数据库
public static void Initialize(IServiceProvider serviceProvider) { using (var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope()) { var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>(); //do your stuff.... context.Database.EnsureCreated(); var subject1 = new Subject { Title = "Physics", Description = "The AB Physics course", GradeEarned = null, GradeOverall = null, }; var subject2 = new Subject { Title = "Chemistry", Description = "A AB Chem course", GradeEarned = null, GradeOverall = null, }; var assignment1 = new Assignment { Date = new DateTime(2020, 3, 1, 9, 0, 0), Name = "Assignment 1", Description = "Forces and Newton's Laws of Motion", Score = 80, Weight = 0.2, Subject = subject1 }; var assignment2 = new Assignment { Date = new DateTime(2020, 3, 1, 9, 0, 0), Name = "Assignment 2", Description = "Gravity", Score = 90, Weight = 0.2, Subject = subject1 }; var assignment3 = new Assignment { Date = new DateTime(2020, 3, 1, 9, 0, 0), Name = "Assignment 3", Description = "Frequency", Score = 70, Weight = 0.2, Subject = subject1 }; var exam1 = new Assignment { Date = new DateTime(2020, 5, 1, 10, 0, 0), Name = "Exam 1", Description = "The first exam", Score = 85, Weight = 0.6, Subject = subject2 }; var exam2 = new Assignment { Date = new DateTime(2020, 6, 1, 11, 0, 0), Name = "Exam 2", Description = "The second exam", Score = 75, Weight = 0.6, Subject = subject2 }; var assignmentz1 = new Assignment { Date = new DateTime(2020, 5, 11, 12, 0, 0), Name = "Assignment 1", Description = "The first Chem grade", Score = 85, Weight = 0.2, Subject = subject2 }; context.Subjects.AddRange(new Subject[] { subject1, subject2 }); context.Assignments.AddRange(new Assignment[] { assignment1, assignment2, assignment3, exam1, exam2 }); context.SaveChanges(); } }
如果你坚持要插入
id
的值,你可以尝试modelBuilder.Entity<Post>().HasData
,你可以参考Data Seeding