【问题标题】:The Instance of Entity Type 'Assignment' Cannot Be Tracked While Seeding Database在播种数据库时无法跟踪实体类型“分配”的实例
【发布时间】:2019-06-02 02:05:42
【问题描述】:

我是 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 类:

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

【问题讨论】:

  • AssignmentId 不是Assignment 的PK(主键)吗?如果是(看起来),它应该是唯一的。并且您的种子数据包含重复的 AssignmentIds - 例如,assignment1exam1AssignmentId == 1。您可能应该让数据库生成这些 ID。 Subject 也一样。您基本上需要使用填充的 Assignments 集合创建 Subject 对象(不要指定硬编码的 PK 和 FK),然后只需执行 context.Subjects.AddRange(…) - EF Core 将负责其余的工作。

标签: c# asp.net-core entity-framework-core ef-core-2.2


【解决方案1】:

使用EF Context初始化数据库,不能直接为实体设置key,它是自动生成的。

尝试使用以下代码进行测试:

  1. 型号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; }
    }
    
  2. 型号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; }
    }
    
  3. 种子数据库

    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&lt;Post&gt;().HasData,你可以参考Data Seeding

【讨论】:

    猜你喜欢
    • 2019-10-28
    • 1970-01-01
    • 2017-06-30
    • 1970-01-01
    • 2021-11-29
    • 2021-05-04
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    相关资源
    最近更新 更多