简体   繁体   English

ASP.NET实体框架6 - 不使用具有一对多关系的类来播种数据

[英]ASP.NET Entity Framework 6 - not seeding data with classes that have a one to many relationship

I'm setting up a database on ASP.NET using Entity Framework 6.1.2 code first method and I'm using Visual Studio 2015. The database is for a project I'm working on for a Marina and I've created two class - Boats and Slips. 我正在使用Entity Framework 6.1.2代码第一种方法在ASP.NET上建立一个数据库,我正在使用Visual Studio 2015.该数据库用于我正在为Marina工作的项目,我创建了两个类 - 船和滑动。 Each boat is assigned to a slip and each slip contains boats. 每艘船都配有一个滑道,每个滑道都包含船只。

The classes are as follows: 课程如下:

    namespace DatabaseTest.Models
{
    public class Boat
    {
        public int BoatID { get; set; }
        public string StateRegoNo { get; set; }
        public double Length { get; set; }
        public string Manufacturer { get; set; }
        public string Model { get; set; }
        public int Year { get; set; }

        [EnumDataType(typeof(BoatType)), Display(Name = "Boat Type")]
        public BoatType type { get; set; }

        public int SlipID { get; set; }

        public virtual Slip Slip { get; set; }
    }

    public enum BoatType
    {
        PowerBoat,
        SailBoat
    }
}

    namespace DatabaseTest.Models
{
    public class Slip
    {
        public int SlipID { get; set; }
        public decimal Length { get; set; }
        public decimal Width { get; set; }

        public virtual ICollection<Boat> Boats { get; set; }
    }
}

Here is the configuration file: 这是配置文件:

 namespace DatabaseTest.Migrations
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;
    using DatabaseTest.Models;

    internal sealed class Configuration : DbMigrationsConfiguration<DatabaseTest.Models.MarinaContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }

        protected override void Seed(DatabaseTest.Models.MarinaContext context)
        {
            context.Boats.AddOrUpdate(
                new Boat
                {
                    BoatID = 1,
                    StateRegoNo = "TW207332",
                    Length = 20.01,
                    Manufacturer = "Whittley",
                    Model = "Sea Legend 601",
                    Year = 2002,
                    type = BoatType.PowerBoat,
                    SlipID = 1
                },

                new Boat
                {
                    BoatID = 2,
                    StateRegoNo = "NS210451",
                    Length = 48.38,
                    Manufacturer = "Dufour",
                    Model = "500 Grand Large",
                    Year = 2015,
                    type = BoatType.SailBoat,
                    SlipID = 2
                } 
                );

            context.SaveChanges(); 

            context.Slips.AddOrUpdate(

                new Slip
                {
                    SlipID = 1,
                    Width = 10,
                    Length = 20,
                },

                new Slip
                {
                    SlipID = 2,
                    Width = 10,
                    Length = 20,
                }
                );

        }
    }
}

Now running 'add-migration initial' in the Package Manager creates the following migration file: 现在,在程序包管理器中运行“add-migration initial”会创建以下迁移文件:

    namespace DatabaseTest.Migrations
{
    using System;
    using System.Data.Entity.Migrations;

    public partial class initial : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "dbo.Boats",
                c => new
                    {
                        BoatID = c.Int(nullable: false, identity: true),
                        StateRegoNo = c.String(),
                        Length = c.Double(nullable: false),
                        Manufacturer = c.String(),
                        Model = c.String(),
                        Year = c.Int(nullable: false),
                        type = c.Int(nullable: false),
                        SlipID = c.Int(nullable: false),
                    })
                .PrimaryKey(t => t.BoatID)
                .ForeignKey("dbo.Slips", t => t.SlipID, cascadeDelete: true)
                .Index(t => t.SlipID);

            CreateTable(
                "dbo.Slips",
                c => new
                    {
                        SlipID = c.Int(nullable: false, identity: true),
                        Length = c.Decimal(nullable: false, precision: 18, scale: 2),
                        Width = c.Decimal(nullable: false, precision: 18, scale: 2),
                    })
                .PrimaryKey(t => t.SlipID);

        }

        public override void Down()
        {
            DropForeignKey("dbo.Boats", "SlipID", "dbo.Slips");
            DropIndex("dbo.Boats", new[] { "SlipID" });
            DropTable("dbo.Slips");
            DropTable("dbo.Boats");
        }
    }
}

Then I run 'update-database'. 然后我运行'update-database'。 The database and tables are created but then I get the following error: 'An error occurred while updating the entries. 创建了数据库和表,但后来我收到以下错误: '更新条目时发生错误。 See the inner exception for details.' 有关详细信息,请参阅内部异常。 and no data has been added to the tables. 并且没有数据添加到表中。

So I'm wondering what has possibly gone wrong here. 所以我想知道这里可能出了什么问题。 What is this 'inner exception' and how can I find out what it is? 什么是“内部异常”,我怎样才能知道它是什么?

Can anyone tell me where I've gone wrong? 谁能告诉我哪里出错了?

Thanks 谢谢

David 大卫

Here is the full script from the Package Manager: 以下是包管理器的完整脚本:

    PM> add-migration initial
Scaffolding migration 'initial'.
The Designer Code for this migration file includes a snapshot of your current Code First model. This snapshot is used to calculate the changes to your model when you scaffold the next migration. If you make additional changes to your model that you want to include in this migration, then you can re-scaffold it by running 'Add-Migration initial' again.
PM> update-database
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Applying explicit migrations: [201609162249553_initial].
Applying explicit migration: 201609162249553_initial.
Running Seed method.
System.Data.Entity.Infrastructure.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.Entity.Core.UpdateException: 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_dbo.Boats_dbo.Slips_SlipID". The conflict occurred in database "DatabaseTest.Models.MarinaContext", table "dbo.Slips", column 'SlipID'.
The statement has been terminated.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<Reader>b__c(DbCommand t, DbCommandInterceptionContext`1 c)
   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)
   at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.Execute(Dictionary`2 identifierValues, List`1 generatedValues)
   at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
   --- End of inner exception stack trace ---
   at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
   at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.<Update>b__2(UpdateTranslator ut)
   at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update[T](T noChangesResult, Func`2 updateFunction)
   at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update()
   at System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesToStore>b__35()
   at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
   at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction)
   at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass2a.<SaveChangesInternal>b__27()
   at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
   at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction)
   at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options)
   at System.Data.Entity.Internal.InternalContext.SaveChanges()
   --- End of inner exception stack trace ---
   at System.Data.Entity.Internal.InternalContext.SaveChanges()
   at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
   at System.Data.Entity.DbContext.SaveChanges()
   at DatabaseTest.Migrations.Configuration.Seed(MarinaContext context) in C:\Users\david\Dropbox\WEB DEVELOPMENT COURSE\1428 OBJECT ORIENTED WEB WEB DEVELOPMENT 1\PROJECTS\PopeyeMarina\DatabaseTest\Migrations\Configuration.cs:line 44
   at System.Data.Entity.Migrations.DbMigrationsConfiguration`1.OnSeed(DbContext context)
   at System.Data.Entity.Migrations.DbMigrator.SeedDatabase()
   at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.SeedDatabase()
   at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
   at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
   at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)
   at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.<Update>b__b()
   at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
   at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
   at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run()
   at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
   at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
   at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
   at System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force)
   at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0()
   at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
An error occurred while updating the entries. See the inner exception for details.
PM> 

Ok, now I can see what the inner exception is. 好的,现在我可以看到内部异常是什么。 At the top it says: 在顶部它说:

System.Data.SqlClient.SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.Boats_dbo.Slips_SlipID". The conflict occurred in database "DatabaseTest.Models.MarinaContext", table "dbo.Slips", column 'SlipID'.
The statement has been terminated.

Now I just need to resolve this conflict. 现在我只需要解决这个冲突。

You should first be adding the Slip records, as those SlipID's don't exist yet in the database without performing a SaveChanges() on your context. 您应该首先添加Slip记录,因为在您的上下文中没有执行SaveChanges()的情况下,数据库中尚不存在SlipID。

The code can be further simplified in a single round-trip to the database with the following: 通过以下方式,可以在数据库的单次往返中进一步简化代码:

namespace DatabaseTest.Migrations
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;
    using DatabaseTest.Models;

    internal sealed class Configuration : DbMigrationsConfiguration<DatabaseTest.Models.MarinaContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }

        protected override void Seed(DatabaseTest.Models.MarinaContext context)
        {

            context.Boats.AddOrUpdate(
                new Boat
                {
                    BoatID = 1,
                    StateRegoNo = "TW207332",
                    Length = 20.01,
                    Manufacturer = "Whittley",
                    Model = "Sea Legend 601",
                    Year = 2002,
                    type = BoatType.PowerBoat,
                    Slip = new Slip {
                            SlipID = 1,
                            Width = 10,
                            Length = 20,
                    }
                },
                new Boat
                {
                    BoatID = 2,
                    StateRegoNo = "NS210451",
                    Length = 48.38,
                    Manufacturer = "Dufour",
                    Model = "500 Grand Large",
                    Year = 2015,
                    type = BoatType.SailBoat,
                    Slip = new Slip {
                        SlipID = 2,
                        Width = 10,
                        Length = 20,
                    }
                });

            context.SaveChanges(); 

        }
    }
}

The solution is: 解决方案是:

    namespace DatabaseTest.Migrations
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;
    using DatabaseTest.Models;

    internal sealed class Configuration : DbMigrationsConfiguration<DatabaseTest.Models.MarinaContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }

        protected override void Seed(DatabaseTest.Models.MarinaContext context)
        {

            context.Slips.AddOrUpdate(

                new Slip
                {
                    SlipID = 1,
                    Width = 10,
                    Length = 20,
                },

                new Slip
                {
                    SlipID = 2,
                    Width = 10,
                    Length = 20,
                }
                );

            context.SaveChanges();

            context.Boats.AddOrUpdate(
                new Boat
                {
                    BoatID = 1,
                    StateRegoNo = "TW207332",
                    Length = 20.01,
                    Manufacturer = "Whittley",
                    Model = "Sea Legend 601",
                    Year = 2002,
                    type = BoatType.PowerBoat,
                    SlipID = 1
                },

                new Boat
                {
                    BoatID = 2,
                    StateRegoNo = "NS210451",
                    Length = 48.38,
                    Manufacturer = "Dufour",
                    Model = "500 Grand Large",
                    Year = 2015,
                    type = BoatType.SailBoat,
                    SlipID = 2
                } 
                );

            context.SaveChanges(); 

        }
    }
}

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

相关问题 使用实体框架在 ASP.NET MVC 中为具有一对多关系的数据库播种 - Seeding database with a one-to-many relationship in ASP.NET MVC using Entity Framework ASP.NET MVC 4模板:播种数据(实体框架) - ASP.NET MVC 4 Template: Seeding data (Entity Framework) ASP.net MVC实体框架更新多对多关系 - ASP.net MVC Entity framework update Many to Many relationship ASP.NET MVC 5和实体框架多对多关系 - ASP.NET MVC 5 & Entity Framework many to many relationship ASP.Net实体框架一对多关系:如何建立依赖关系和延迟加载不起作用 - ASP.Net Entity Framework one-to-many relationship: How to establish dependency and lazy loading not working 使用 Fluent API 使用 Entity Framework 6 在 asp.net 中配置一对多关系 - Configuring one to Many relationship in asp.net with Entity Framework 6 with Fluent API ASP.NET Identity 3.0实体框架数据库种子 - ASP.NET Identity 3.0 Entity Framework Database Seeding 使用Asp.net Boilerplate在Entity Framework中进行多对多关系复制记录 - Duplicating record in Entity Framework many to many relationship using Asp.net Boilerplate ASP .NET 核心 MVC 实体框架 - 将数据添加到多对多关系中 - ASP .NET Core MVC Entity Framework - add data into many-to-many relationship 在asp.net实体框架中以一对一的关系使两个模型彼此了解 - make both models aware of each other with a one-to-one relationship in asp.net entity framework
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM