Sea*_*lak 5 c# sql sql-server entity-framework ef-core-2.2
我已经从现有数据库创建了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;
Run Code Online (Sandbox Code Playgroud)
而且我不知道这是如何导致针对'BirdBrain.dbo.services'数据库运行更新的BirdBrain_test。
相关的DbContext代码
Server=****;Database=BirdBrain_test;User Id=****;Password=****;Trusted_Connection=False;Multisubnetfailover=true;
Run Code Online (Sandbox Code Playgroud)
关联的表我正在使用TableAttribute来引用表名。
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())");
});
}
}
Run Code Online (Sandbox Code Playgroud)
相关更新代码
[Table("services")]
public class Service
{
...
}
Run Code Online (Sandbox Code Playgroud)
获取,插入和删除在同一张表上进行。
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'.
Run Code Online (Sandbox Code Playgroud)
编辑:我按照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
Run Code Online (Sandbox Code Playgroud)
问题在于使用该BirdBrain.dbo.services命名的数据库上存在底层更新触发器。我测试了将命名更改为servicesfrom BirdBrain.dbo.services,这解决了错误。最终我完全删除了触发器,因为它处理的逻辑目前是不必要的。
为了解决这个问题,我按照 @IvanStoev 的建议向 DbContext 添加了日志记录,并确认 EF 实际上services正确地定位了对象,而不是 BirdBrain.dbo.services我最初认为的那样。
然后,我使用 SSMS 连接到数据库并扩展表以查看其触发器,这就是我发现违规触发器的地方。
如果您遇到类似的问题,您应该检查您正在修改的表上是否有任何触发器。