为什么FirstOrDefault会调用SaveChanges?

时间:2013-10-09 03:29:00

标签: winforms entity-framework-5

在以下代码中,ConfigSetting是一个实体,Db是我的Context。 当我在调试器中进入以下行时

 ConfigSetting config = this.Db.ConfigSettings.FirstOrDefault(o => o.Name == kSiteGuid);

我发现我在上下文SaveChanges事件中。

数据库已经存在,因此EF不应该尝试播种它。

调用堆栈是

  

SBD.Syrius.DataLayer.dll!SBD.Syrius.DataLayer.Context.SaveChanges()第338行C#       EntityFramework.dll!System.Data.Entity.Migrations.DbMigrator.SeedDatabase()+ 0x9e bytes
      EntityFramework.dll!System.Data.Entity.Migrations.Infrastructure.MigratorBase.SeedDatabase()+ 0x40 bytes
      EntityFramework.dll!System.Data.Entity.Migrations.DbMigrator.Upgrade(System.Collections.Generic.IEnumerable pendingMigrations,string targetMigrationId,string lastMigrationId)+ 0x38c bytes
      EntityFramework.dll!System.Data.Entity.Migrations.Infrastructure.MigratorBase.Upgrade(System.Collections.Generic.IEnumerable pendingMigrations,string targetMigrationId,string lastMigrationId)+ 0x5e bytes
      EntityFramework.dll!System.Data.Entity.Migrations.DbMigrator.Update(string targetMigration)+ 0x547 bytes
      EntityFramework.dll!System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update()+ 0x34 bytes       EntityFramework.dll!System.Data.Entity.MigrateDatabaseToLatestVersion.InitializeDatabase(SBD.Syrius.DataLayer.Context context)+ 0xa3 bytes       EntityFramework.dll!System.Data.Entity.Database.SetInitializerInternal.AnonymousMethod_ 0(System.Data.Entity.DbContext c)+ 0xd0 bytes
      EntityFramework.dll!System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization.AnonymousMethod
_6()+ 0x55 bytes       EntityFramework.dll!System.Data.Entity.Internal.InternalContext.PerformInitializationAction(System.Action action)+ 0x74 bytes
      EntityFramework.dll!System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization()+ 0x17d bytes
      EntityFramework.dll!System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase.AnonymousMethod__4(System.Data.Entity.Internal.InternalContext c)+ 0x30 bytes
      EntityFramework.dll!System.Data.Entity.Internal.RetryAction.PerformAction(System.Data.Entity.Internal.InternalContext input)+ 0xa2 bytes
      EntityFramework.dll!System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(System.Action action)+ 0x181 bytes
      EntityFramework.dll!System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase()+ 0xa5 bytes
      EntityFramework.dll!System.Data.Entity.Internal.InternalContext.Initialize()+ 0x46 bytes
      EntityFramework.dll!System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(System.Type entityType)+ 0x2d bytes       EntityFramework.dll!System.Data.Entity.Internal.Linq.InternalSet.Initialize()+ 0x97 bytes
      EntityFramework.dll!System.Data.Entity.Internal.Linq.InternalSet.InternalContext.get()+ 0x32 bytes       EntityFramework.dll!System.Data.Entity.Infrastructure.DbQuery.System.Linq.IQueryable.Provider.get()+ 0x8c bytes
      System.Core.dll!System.Linq.Queryable.FirstOrDefault(System.Linq.IQueryable source,System.Linq.Expressions.Expression>谓词)+ 0x55字节
      SBD.Syrius.DataLayer.dll!SBD.Syrius.DataLayer.DataHelper.FindOrCreateSite()第262行+ 0x1d6字节C#       SBD.Syrius.UI.exe!SBD.Syrius.UI.Program.Main(string [] args)第34行+ 0x24字节C#       [原产于管理过渡]
      [管理到原生过渡]
      mscorlib.dll!System.Runtime.Hosting.ApplicationActivator.CreateInstance(System.ActivationContext activationContext,string [] activationCustomData)+ 0x66 bytes       Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone()+ 0x8d bytes
      mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext,System.Threading.ContextCallback callback,object state,bool preserveSyncCtx)+ 0x285 bytes       mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext,System.Threading.ContextCallback callback,object state,bool preserveSyncCtx)+ 0x9 bytes
      mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext,System.Threading.ContextCallback回调,对象状态)+ 0x57字节
      mscorlib.dll!System.Threading.ThreadHelper.ThreadStart()+ 0x51 bytes
      [原生于管理过渡]

调试器显示

  

' SBD.Syrius.UI.vshost.exe' (托管(v4.0.30319)):已加载' E:\ EShared \ Syrius6 \ syrius_syrius \ SBD.Syrius.UI \ bin \ Debug \ SBD.Syrius.Synchronisation.dll',已加载符号。   类型' System.Data.SqlClient.SqlException'的第一次机会异常发生在System.Data.dll中   类型' System.Data.SqlClient.SqlException'的第一次机会异常发生在System.Data.dll中   类型' System.Data.SqlClient.SqlException'的第一次机会异常发生在System.Data.dll中   类型为System.Data.EntityCommandExecutionException'的第一次机会异常。发生在System.Data.Entity.dll中   类型为System.Data.EntityCommandExecutionException'的第一次机会异常。发生在System.Data.Entity.dll中   类型为System.Data.EntityCommandExecutionException'的第一次机会异常。发生在System.Data.Entity.dll中   步入:踩过没有符号的方法&System; System.Data.Entity.Infrastructure.DbContextInfo.CreateActivator.AnonymousMethod__0'   步入:踩过没有符号的方法&System; System.Data.Entity.Infrastructure.DbContextInfo.CreateInstance'   单步执行:单步执行没有符号的方法' System.Data.Entity.Migrations.DbMigrator.SeedDatabase'

[更新]

有关初始化程序的信息

    private static string _connectionString;

    public Context()
        : base(_connectionString )
    {
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<Context, Configuration>());

    }

    public Context(string connString)
        : base(connString)
    {

        _connectionString = connString;
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<Context, Configuration>());


    }

    public Context(string connString )
        : base(connString)
    {
        _connectionString = connString;

    }

对于Configuration类

namespace SBD.Syrius.DataLayer.Migrations
{

  using System.Data.Entity.Migrations;


  public sealed class Configuration : DbMigrationsConfiguration<SBD.Syrius.DataLayer.Context>
  {
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
    }

    protected override void Seed(SBD.Syrius.DataLayer.Context context)
    {

    }
  }
}

2 个答案:

答案 0 :(得分:0)

如果查看调用堆栈,可以看到它正在进行数据库迁移。这是您对模型进行更改时发生的过程,并且需要更新数据库结构。

迁移发生后,EF会调用SeedDatabase,它允许您添加默认值。在SeedDatabase的末尾,它调用SaveChanges来保存这些更改。

答案 1 :(得分:0)

当我尝试创建新实体时,在我的UnitOfWork的GenericRepository.cs中调用了此异常。

 public virtual void Insert(TEntity entity)
    {
        dbSet.Add(entity);
    }

轻松修复

在程序包管理器控制台中。添加新迁移Add-Migration SomeMeaninglessName并更新数据库Update-Database