繁体   English   中英

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

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

我正在使用Entity Framework 6.1.2代码第一种方法在ASP.NET上建立一个数据库,我正在使用Visual Studio 2015.该数据库用于我正在为Marina工作的项目,我创建了两个类 - 船和滑动。 每艘船都配有一个滑道,每个滑道都包含船只。

课程如下:

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

这是配置文件:

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

        }
    }
}

现在,在程序包管理器中运行“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");
        }
    }
}

然后我运行'update-database'。 创建了数据库和表,但后来我收到以下错误: '更新条目时发生错误。 有关详细信息,请参阅内部异常。 并且没有数据添加到表中。

所以我想知道这里可能出了什么问题。 什么是“内部异常”,我怎样才能知道它是什么?

谁能告诉我哪里出错了?

谢谢

大卫

以下是包管理器的完整脚本:

    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> 

好的,现在我可以看到内部异常是什么。 在顶部它说:

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.

现在我只需要解决这个冲突。

您应该首先添加Slip记录,因为在您的上下文中没有执行SaveChanges()的情况下,数据库中尚不存在SlipID。

通过以下方式,可以在数据库的单次往返中进一步简化代码:

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

        }
    }
}

解决方案是:

    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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM