Entity Framework 仅在更新时抛出异常 - 对象名称无效 'dbo.BirdBrain.service'
Entity Framework throws exception on updates only - Invalid object name 'dbo.BirdBrain.service'
我已经从现有数据库创建了一个 EF Core 模型,除了更新之外,对实体的所有操作都有效;更新时 EF Core 使用了不正确的数据库名称。
例如。当我执行更新时,我得到 SqlException: Invalid object name 'BirdBrain.dbo.services'.
。 BirdBrainContext
是我的 DbContext 的名称,但我要连接的数据库是 BirdBrain_test
.
我尝试从 EF Core 2.1 更新到 EF Core 2.2,但问题仍然存在。当连接到名为 BirdBrain
的生产数据库时,相同的代码可以完美运行。
我正在使用如下所示的连接字符串初始化我的上下文
Server=****;Database=BirdBrain_test;User Id=****;Password=****;Trusted_Connection=False;Multisubnetfailover=true;
我不知道当数据库为 BirdBrain_test
.
时,这如何导致更新 运行 而不是 'BirdBrain.dbo.services'
相关DbContext代码
public class BirdBrainContextFactory
{
private readonly string _connectionString;
public BirdBrainContextFactory(string connectionString)
{
_connectionString = connectionString;
}
public BirdBrainContext Create()
{
var optionsBuilder = new DbContextOptionsBuilder<BirdBrainContext>();
optionsBuilder.UseSqlServer(_connectionString);
return new BirdBrainContext(optionsBuilder.Options);
}
}
public class BirdBrainContext : DbContext
{
public BirdBrainContext(DbContextOptions<BirdBrainContext> options)
: base(options)
{
}
public DbSet<Service> Services { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Service>(entity =>
{
entity.HasIndex(e => e.Tag)
.IsUnique();
entity.Property(e => e.CreatedAt)
.HasDefaultValueSql("(getutcdate())");
entity.Property(e => e.UpdatedAt)
.HasDefaultValueSql("(getutcdate())");
});
}
}
关联的table我正在使用TableAttribute来引用table名称。
[Table("services")]
public class Service
{
...
}
相关更新代码
public Service UpdateService(Service service)
{
using (var context = _contextFactory.Create())
{
EnforceServiceExists(context, service);
context.Entry(service).State = EntityState.Modified;
context.SaveChanges();
return service;
}
}
获取、插入和删除同样适用于此 table。
Microsoft.EntityFrameworkCore.DbUpdateException
HResult=0x80131500
Message=An error occurred while updating the entries. See the inner exception for details.
Source=Microsoft.EntityFrameworkCore.Relational
StackTrace:
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(DbContext _, ValueTuple`2 parameters)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable`1 commandBatches, IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IReadOnlyList`1 entries)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IReadOnlyList`1 entriesToSave)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
at DataService.BirdBrainContext.SaveChanges() in C:\git\BirdBrainAPI\src\DataService\BirdBrainContext.cs:line 180
...
Inner Exception 1:
SqlException: Invalid object name 'BirdBrain.dbo.services'.
编辑:我按照 Ivan Stoev 的建议添加了 EF Core 日志记录,并在下方粘贴了更新结果。看起来 EF 正在连接到 BirdBrain_test
数据库并且 运行 宁 UPDATE [services] ...
而不是错误提示的 UPDATE [BirdBrain].[dbo].[services]
。仍然不确定发生了什么。
dbug: Microsoft.EntityFrameworkCore.Database.Connection[20001]
Opened connection to database 'BirdBrain_test' on server '****'.
dbug: Microsoft.EntityFrameworkCore.Database.Transaction[20200]
Beginning transaction with isolation level 'ReadCommitted'.
dbug: Microsoft.EntityFrameworkCore.Database.Command[20100]
Executing DbCommand [Parameters=[@p19='?' (DbType = Int32), @p0='?' (DbType = DateTime), ...], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
UPDATE [services] SET [created_at] = @p0, ... , [updated_at] = @p18
WHERE [id] = @p19;
SELECT @@ROWCOUNT;
fail: Microsoft.EntityFrameworkCore.Database.Command[20102]
Failed executing DbCommand (61ms) [Parameters=[@p19='?' (DbType = Int32), @p0='?' (DbType = DateTime), ...], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
UPDATE [services] SET [created_at] = @p0, ... , [updated_at] = @p18
WHERE [id] = @p19;
SELECT @@ROWCOUNT;
System.Data.SqlClient.SqlException (0x80131904): Invalid object name 'BirdBrain.dbo.services'.
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)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader()
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, DbCommandMethod executeMethod, IReadOnlyDictionary`2 parameterValues)
ClientConnectionId:b2b87fd1-8e34-4fcf-80f1-290de30b28dd
Error Number:208,State:1,Class:16
问题是在使用 BirdBrain.dbo.services
命名的数据库上有一个基础更新触发器。我测试了将命名从 BirdBrain.dbo.services
更改为 services
,这解决了错误。最终我完全删除了触发器,因为它处理的逻辑在目前是不必要的。
为了解决这个问题,我按照@IvanStoev 的建议添加了 logging to the DbContext,并确认 EF 实际上是正确地针对 services
对象,而 不是 BirdBrain.dbo.services
正如我最初相信的那样。
然后我使用 SSMS 连接到数据库并展开 table 以查看其触发器,这是我发现有问题的触发器的地方。
如果您遇到类似的问题,您应该检查您正在修改的 table 上是否有任何触发器。
我已经从现有数据库创建了一个 EF Core 模型,除了更新之外,对实体的所有操作都有效;更新时 EF Core 使用了不正确的数据库名称。
例如。当我执行更新时,我得到 SqlException: Invalid object name 'BirdBrain.dbo.services'.
。 BirdBrainContext
是我的 DbContext 的名称,但我要连接的数据库是 BirdBrain_test
.
我尝试从 EF Core 2.1 更新到 EF Core 2.2,但问题仍然存在。当连接到名为 BirdBrain
的生产数据库时,相同的代码可以完美运行。
我正在使用如下所示的连接字符串初始化我的上下文
Server=****;Database=BirdBrain_test;User Id=****;Password=****;Trusted_Connection=False;Multisubnetfailover=true;
我不知道当数据库为 BirdBrain_test
.
'BirdBrain.dbo.services'
相关DbContext代码
public class BirdBrainContextFactory
{
private readonly string _connectionString;
public BirdBrainContextFactory(string connectionString)
{
_connectionString = connectionString;
}
public BirdBrainContext Create()
{
var optionsBuilder = new DbContextOptionsBuilder<BirdBrainContext>();
optionsBuilder.UseSqlServer(_connectionString);
return new BirdBrainContext(optionsBuilder.Options);
}
}
public class BirdBrainContext : DbContext
{
public BirdBrainContext(DbContextOptions<BirdBrainContext> options)
: base(options)
{
}
public DbSet<Service> Services { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Service>(entity =>
{
entity.HasIndex(e => e.Tag)
.IsUnique();
entity.Property(e => e.CreatedAt)
.HasDefaultValueSql("(getutcdate())");
entity.Property(e => e.UpdatedAt)
.HasDefaultValueSql("(getutcdate())");
});
}
}
关联的table我正在使用TableAttribute来引用table名称。
[Table("services")]
public class Service
{
...
}
相关更新代码
public Service UpdateService(Service service)
{
using (var context = _contextFactory.Create())
{
EnforceServiceExists(context, service);
context.Entry(service).State = EntityState.Modified;
context.SaveChanges();
return service;
}
}
获取、插入和删除同样适用于此 table。
Microsoft.EntityFrameworkCore.DbUpdateException
HResult=0x80131500
Message=An error occurred while updating the entries. See the inner exception for details.
Source=Microsoft.EntityFrameworkCore.Relational
StackTrace:
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(DbContext _, ValueTuple`2 parameters)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable`1 commandBatches, IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IReadOnlyList`1 entries)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IReadOnlyList`1 entriesToSave)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
at DataService.BirdBrainContext.SaveChanges() in C:\git\BirdBrainAPI\src\DataService\BirdBrainContext.cs:line 180
...
Inner Exception 1:
SqlException: Invalid object name 'BirdBrain.dbo.services'.
编辑:我按照 Ivan Stoev 的建议添加了 EF Core 日志记录,并在下方粘贴了更新结果。看起来 EF 正在连接到 BirdBrain_test
数据库并且 运行 宁 UPDATE [services] ...
而不是错误提示的 UPDATE [BirdBrain].[dbo].[services]
。仍然不确定发生了什么。
dbug: Microsoft.EntityFrameworkCore.Database.Connection[20001]
Opened connection to database 'BirdBrain_test' on server '****'.
dbug: Microsoft.EntityFrameworkCore.Database.Transaction[20200]
Beginning transaction with isolation level 'ReadCommitted'.
dbug: Microsoft.EntityFrameworkCore.Database.Command[20100]
Executing DbCommand [Parameters=[@p19='?' (DbType = Int32), @p0='?' (DbType = DateTime), ...], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
UPDATE [services] SET [created_at] = @p0, ... , [updated_at] = @p18
WHERE [id] = @p19;
SELECT @@ROWCOUNT;
fail: Microsoft.EntityFrameworkCore.Database.Command[20102]
Failed executing DbCommand (61ms) [Parameters=[@p19='?' (DbType = Int32), @p0='?' (DbType = DateTime), ...], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
UPDATE [services] SET [created_at] = @p0, ... , [updated_at] = @p18
WHERE [id] = @p19;
SELECT @@ROWCOUNT;
System.Data.SqlClient.SqlException (0x80131904): Invalid object name 'BirdBrain.dbo.services'.
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)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader()
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, DbCommandMethod executeMethod, IReadOnlyDictionary`2 parameterValues)
ClientConnectionId:b2b87fd1-8e34-4fcf-80f1-290de30b28dd
Error Number:208,State:1,Class:16
问题是在使用 BirdBrain.dbo.services
命名的数据库上有一个基础更新触发器。我测试了将命名从 BirdBrain.dbo.services
更改为 services
,这解决了错误。最终我完全删除了触发器,因为它处理的逻辑在目前是不必要的。
为了解决这个问题,我按照@IvanStoev 的建议添加了 logging to the DbContext,并确认 EF 实际上是正确地针对 services
对象,而 不是 BirdBrain.dbo.services
正如我最初相信的那样。
然后我使用 SSMS 连接到数据库并展开 table 以查看其触发器,这是我发现有问题的触发器的地方。
如果您遇到类似的问题,您应该检查您正在修改的 table 上是否有任何触发器。