【发布时间】:2019-07-12 19:00:57
【问题描述】:
我已经从现有数据库创建了一个 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())");
});
}
}
关联的表我使用TableAttribute来引用表名。
[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;
}
}
获取、插入和删除在同一个表上工作。
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
【问题讨论】:
-
您是否使用了使用 3 部分命名进行编码的 SP?
-
是的,
BirdBrain.dbo.来自哪里?通常是 EF Core 2.2。不向表名添加模式前缀。是否有一些数据注释或流利的配置未在帖子中显示? -
@Larnu 我没有使用任何存储过程
-
这当然很奇怪。可能来自 db trigger (
instead of update?) 之类的。打开 EF Core Logging 并查看 EF Core 尝试执行的 SQL 命令。 -
证明问题不在EF Core。由于您使用的是现有数据库,因此您必须检查数据库。例如,使用 VS SqlServer 对象资源管理器,连接到数据库,展开表 - dbo.services,然后查看代码或查看设计器并在里面寻找
BirdBrain。或联系数据库设计者/管理员。谁知道,services甚至可能不是表,而是视图,或者可能有触发器替换插入、更新、删除,更新触发器有错误。在 EF Core 方面您无能为力。
标签: c# sql sql-server entity-framework ef-core-2.2