【发布时间】:2015-06-24 12:52:44
【问题描述】:
当我尝试将新学生插入现有 schoolclassCode 时,为什么会收到 DbUpdateException - 没有更多详细信息?
这是一个多对多的关系。
var schoolclassCode = await context.SchoolclassCodes.SingleAsync(s => s.Id == pupil.SchoolclassCodeId);
schoolclassCode.Pupils.Add(pupil);
context.Entry(schoolclassCode).State = EntityState.Modified;
int count = await context.SaveChangesAsync();
是否必须先在 context.Pupils.add(pupil) 中插入瞳孔?
我认为我可以在 ONE 中插入学生并设置与学校课程代码的关系
schoolclassCode.Pupils.Add(pupil);
然后将 schoolclassCode 设置为已修改。
如何在与现有委托人/父实体的多对多关系中插入实体?
更新
System.Data.Entity.Infrastructure.DbUpdateException was unhandled by user code
HResult=-2146233087
Message=An error occurred while updating the entries. See the inner exception for details.
Source=mscorlib
StackTrace:
bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
bei System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
bei TGB.Repository.PupilRepository.<AddPupil>d__8.MoveNext() in c:\Repository\TGB\TGB.Repository\PupilRepository.cs:Zeile 29.
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
bei System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
bei Business.IntegrationTests.PupilRepositoryTests.CreatePupil() in c:\TGB\IntegrationTests\PupilRepositoryTests.cs:Zeile 31.
InnerException: System.Data.Entity.Core.UpdateException
HResult=-2146233087
Message=An error occurred while updating the entries. See the inner exception for details.
Source=EntityFramework
StackTrace:
bei System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.<UpdateAsync>d__0.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
bei System.Data.Entity.Core.Objects.ObjectContext.<ExecuteInTransactionAsync>d__3d`1.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
bei System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesToStoreAsync>d__39.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
bei System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.<ExecuteAsyncImplementation>d__9`1.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
bei System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesInternalAsync>d__31.MoveNext()
InnerException: System.Data.SqlClient.SqlException
HResult=-2146232060
Message=Timeout abgelaufen. Das Zeitlimit wurde vor dem Beenden des Vorgangs überschritten oder der Server reagiert nicht.
Source=.Net SqlClient Data Provider
ErrorCode=-2146232060
Class=11
LineNumber=0
Number=-2
Procedure=""
Server=MyAccount\SQLEXPRESS
State=0
StackTrace:
bei System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
bei System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
bei System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
bei System.Data.SqlClient.SqlCommand.EndExecuteNonQueryInternal(IAsyncResult asyncResult)
bei System.Data.SqlClient.SqlCommand.EndExecuteNonQueryAsync(IAsyncResult asyncResult)
bei System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
bei System.Data.Entity.Utilities.TaskExtensions.CultureAwaiter`1.GetResult()
bei System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.<ExecuteAsync>d__0.MoveNext()
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
bei System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.<UpdateAsync>d__0.MoveNext()
InnerException: System.ComponentModel.Win32Exception
HResult=-2147467259
Message=Der Wartevorgang wurde abgebrochen
ErrorCode=-2147467259
NativeErrorCode=258
InnerException:
更新 2
public class SchoolclassCode
{
public SchoolclassCode()
{
Pupils = new HashSet<Pupil>();
}
public int Id { get; set; }
public ISet<Pupil> Pupils { get; set; }
}
public class Pupil
{
public Pupil()
{
SchoolclassCodes = new HashSet<SchoolclassCode>();
}
public int Id { get; set; }
public ISet<SchoolclassCode> SchoolclassCodes { get; set; }
[NotMapped]
public int SchoolclassCodeId { get; set; }
}
实际上,多对多关系应该按照惯例起作用,但由于我无法解释的 DbUpdateException 行为,我仍然明确设置了 SchoolclassCode 和 Pupil 之间的配置。
public class SchoolclassCodeConfiguration : EntityTypeConfiguration<SchoolclassCode>
{
public SchoolclassCodeConfiguration()
{
base.Property(p => p.SchoolclassNumber).IsRequired().HasMaxLength(10);
base.Property(p => p.SubjectName).IsRequired().HasMaxLength(10);
base.Property(p => p.ClassIdentifier).IsOptional().HasMaxLength(2);
base.HasMany(p => p.Pupils)
.WithMany(p => p.SchoolclassCodes)
.Map(x =>
{
x.MapLeftKey("SchoolclassCodeId");
x.MapRightKey("PupilId");
x.ToTable("SchoolclassCodePupil");
});
}
}
LOG ERRORS发生在我的 Attach Pupil 方法中的 SaveChanges 上
UPDATE [dbo].[SchoolclassCode]
SET [SchoolclassNumber] = @0, [SubjectName] = @1, [Color] = @2, [ClassIdentifier] = @3, [SchoolyearId] = @4
WHERE ([Id] = @5)
-- @0: '7' (Type = String, Size = 10)
-- @1: 'Math' (Type = String, Size = 10)
-- @2: '5' (Type = Int32)
-- @3: 'a' (Type = String, Size = 2)
-- @4: '1' (Type = Int32)
-- @5: '1' (Type = Int32)
-- Executing asynchronously at 24.06.2015 16:57:57 +02:00
-- Completed in 8 ms with result: 1
INSERT [dbo].[Pupil]([FirstName], [LastName], [Postal], [City], [Street])
VALUES (@0, @1, NULL, NULL, NULL)
SELECT [Id]
FROM [dbo].[Pupil]
WHERE @@ROWCOUNT > 0 AND [Id] = scope_identity()
-- @0: 'Max' (Type = String, Size = 25)
-- @1: 'Mustermann' (Type = String, Size = 25)
-- Executing asynchronously at 24.06.2015 16:49:30 +02:00
-- Completed in 2 ms with result: SqlDataReader
INSERT [dbo].[SchoolclassCodePupil]([SchoolclassCodeId], [PupilId])
VALUES (@0, @1)
-- @0: '1' (Type = Int32)
-- @1: '1' (Type = Int32)
-- Executing asynchronously at 24.06.2015 16:49:30 +02:00
-- Completed in 2 ms with result: 1
Committed transaction at 24.06.2015 16:49:30 +02:00
Closed connection at 24.06.2015 16:49:30 +02:00
The thread 0x60 has exited with code 259 (0x103).
The thread 0x1178 has exited with code 259 (0x103).
The thread 0xdc0 has exited with code 259 (0x103).
A first chance exception of type 'System.NullReferenceException' occurred in Business.IntegrationTests.dll
真正的问题
是我注释掉的每个测试之前和之后的 TransactionScope,然后一切正常!
为什么我在使用此代码时会收到此异常 - 其他测试 + TransactionScope 工作正常!!! -
public abstract class IntegrationTestsBase
{
protected TransactionScope TransactionScope;
[TestInitialize]
public void TestSetup()
{
TransactionScope = new TransactionScope();
}
[TestCleanup]
public void TestCleanup()
{
TransactionScope.Dispose();
}
}
【问题讨论】:
-
DbUpdateException通常表示数据库级别出现问题,而不是 EF 级别。通常,内部异常会有更多有趣的细节。你能发布完整的异常堆栈跟踪吗? -
很好认!请参阅我更新的问题。真正的错误并不多。但是错误来源是sql数据提供者而不是EF。
-
我还更新了两个参与实体的问题,以防仍有问题......
-
我无法翻译,但听起来你有超时?
Timeout abgelaufen. Das Zeitlimit wurde vor dem Beenden des Vorgangs überschritten oder der Server reagiert nicht.。也许您可以尝试记录生成的 SQL 语句以查看它们有什么问题,添加以下代码:context.Database.Log = s => Debug.WriteLine(s); -
使用日志记录详细信息更新了问题,并通过更新 SchoolclassCode 更正了日志记录详细信息!
标签: c# entity-framework entity-framework-6.1