Экземпляр типа объекта «Назначение» не может быть отслежен при заполнении базы данных - PullRequest
0 голосов
/ 02 июня 2019

Я новичок в Entity Framework Core, и у меня были проблемы с заполнением базы данных mssql. У меня есть модель Subject и модель Assignment с отношением один ко многим (Subject имеет 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);
        }
    }
}

1 Ответ

0 голосов
/ 27 июня 2019

Для инициализации базы данных с EF Context вы не можете установить ключ для сущности напрямую, он генерируется автоматически.

Попробуйте сделать тест с кодом ниже:

  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<Post>().HasData, и вы можете сослаться на Заполнение данных

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...