簡體   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