这是一个奇怪的错误,没有用Google搜索。
我尝试创建并插入AssetOwner记录。但我收到错误" System.Data.SqlClient.SqlException"由于两个表上的外键关系(显然)与我尝试的SQL语句无关:
INSERT语句与FOREIGN KEY约束冲突 " FK_Adjustments_AdjustmentProcesses&#34 ;.冲突发生在 数据库" TPS_2",表" dbo.AdjustmentProcesses",列' ID'。该 声明已被终止。
以下是抛出错误的代码段(由注释指示)(" da"就像存储库一样):
var add = new AssetOwner()
{
Client = da.Clients.Get(adjustment.ToClientID),
Asset = da.Assets.Get(adjustment.AssetID),
StartDate = adjustment.EffectiveDate
};
da.AssetOwners.Add(add);
var remove = da.AssetOwners.GetCurrentOwner(da.Assets.Get(adjustment.AssetID));
remove.EndDate = adjustment.EffectiveDate;
da.SaveChanges(); // Exception here (this is DataContext.SubmitChanges())
这里有关于表格和关系的小图片:
抛出错误的关系已突出显示为红色,有问题的表格已用红色圈出 - 如您所见,AssetOwner的插入内容似乎与调整调整过程关系无关?
我使用Visual Studio生成的LINQ-to-SQL类,有时我在DataContext的刷新版本中注意到了奇怪的gremlins。因此,我的第一个想法是删除有问题的关系,重新生成,重新创建关系,重新生成。这没有成功。
我已经完成了几次代码 - 值得注意的是,在此代码之前控制器操作中没有其他SQL语句 - 我无法看到任何可能的原因导致此异常。不过,我将在这里重现整个控制器动作(希望长代码片段不会阻止任何潜在的读者):
public ActionResult ManualEntry(int id, FormCollection collection)
{
// Grab the adjustment process
var process = da.AdjustmentProcesses.Get(id);
// Map a dto and set the details needed for the view
var dto = new AdjustmentProcessViewModel();
Adapter.MapDto(dto, process, da);
Adapter.SetDetails(dto, da);
// Generate the premium values for those policies we can
var pg = new PremiumGenerator(da);
foreach (var apd in dto.AdjustmentPolicyDetails)
{
if (apd.CanAutoGenerate == true)
pg.GeneratePremiumValues(dto.Policies[apd.Index]);
}
// Update the model from the form collection
TryUpdateModel(dto.Policies, "Policies");
// Run Validation
var invalids = 0;
foreach (var apd in dto.AdjustmentPolicyDetails)
{
var policy = dto.Policies[apd.Index];
var validator = new PolicyValidator(da);
validator.Validate(policy);
if (!validator.IsValid)
{
invalids++;
foreach (var ruleViolation in validator.RuleViolations)
apd.RuleViolations.Add(new RuleViolation(ruleViolation.ErrorMessage, "Policies[" + apd.Index.ToString() + "]." + ruleViolation.PropertyName));
this.MergeRuleViolations(apd.RuleViolations);
}
}
// If validation has failed, return the view
if (invalids > 0)
return View(dto);
else // Otherwise process the adjustments
{
foreach (var adjustment in da.Adjustments.GetAdjustmentsForProcess(process.ID))
{
if (adjustment.ActionID == (int)AdjustmentAction.Add)
{
var add = new AssetOwner()
{
Client = da.Clients.Get(adjustment.ClientID),
Asset = da.Assets.Get(adjustment.AssetID),
StartDate = adjustment.EffectiveDate
};
da.AssetOwners.Add(add);
da.SaveChanges();
}
else if (adjustment.ActionID == (int)AdjustmentAction.Remove)
{
var remove = da.AssetOwners.GetCurrentOwner(da.Assets.Get(adjustment.AssetID));
remove.EndDate = adjustment.EffectiveDate;
da.SaveChanges();
}
else if (adjustment.ActionID == (int)AdjustmentAction.Transfer)
{
var add = new AssetOwner()
{
Client = da.Clients.Get(adjustment.ToClientID),
Asset = da.Assets.Get(adjustment.AssetID),
StartDate = adjustment.EffectiveDate
};
da.AssetOwners.Add(add);
var remove = da.AssetOwners.GetCurrentOwner(da.Assets.Get(adjustment.AssetID));
remove.EndDate = adjustment.EffectiveDate;
da.SaveChanges();
}
}
var policyAdapter = new PolicyAdapter();
foreach (var policy in dto.Policies)
{
var newPolicy = new Policy();
policyAdapter.MapObject(newPolicy, policy, da);
var validator = new PolicyValidator(da);
validator.Validate(newPolicy);
if (!validator.IsValid)
throw new Exception();
else
{
da.Policies.Add(newPolicy);
da.SaveChanges();
}
}
}
return RedirectToAction("Index");
}
也许一个线索是我正在研究的对象是"转移" (沿着那个代码路径)抛出错误,而"添加"或"删除"两者都工作正常而不会抛出错误。尽管如此,代码实际上是相同的,并且DB表中的所有调整对象都满足外键约束。
为了进一步帮助排除故障,这里是堆栈跟踪:
System.Data.SqlClient.SqlException(0x80131904):INSERT语句 与FOREIGN KEY约束冲突 " FK_Adjustments_AdjustmentProcesses&#34 ;.冲突发生在 数据库" TPS_2",表" dbo.AdjustmentProcesses",列' ID'。该 声明已经终止。在 System.Data.SqlClient.SqlConnection.OnError(SqlException异常, Boolean breakConnection)at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler,SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject System.Data.SqlClient.SqlDataReader.ConsumeMetaData()中的stateObj) 在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)at System.Data.SqlClient.SqlCommand.RunExecuteReader(的CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String 方法,DbAsyncResult结果)at System.Data.SqlClient.SqlCommand.RunExecuteReader(的CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String 方法)at System.Data.SqlClient.SqlCommand.ExecuteReader(的CommandBehavior 行为,String方法)at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(的CommandBehavior 行为) System.Data.Linq.SqlClient.SqlProvider.Execute(表达式查询, QueryInfo queryInfo,IObjectReaderFactory factory,Object [] parentArgs,Object [] userArgs,ICompiledSubQuery [] subQueries,Object lastResult)at System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(表达式查询, QueryInfo [] queryInfos,IObjectReaderFactory factory,Object [] userArguments,ICompiledSubQuery [] subQueries)at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(表达式 查询) System.Data.Linq.ChangeDirector.StandardChangeDirector.DynamicInsert(TrackedObject 项目) System.Data.Linq.ChangeDirector.StandardChangeDirector.Insert(TrackedObject 项目) System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode)at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
在TPS.Models.TPSDataAccess.SaveChanges()中 C:\ Users \ tim.niven.KJRG \ Documents \ Visual Studio 2010 \项目\ TPS-干线\ TPS \ TPS \型号\ MainObjects \ TPSDataAccess.cs:行 169 at TPS.Areas.Clients.Controllers.AdjustmentProcessController.ManualEntry(的Int32 id,FormCollection集合) C:\ Users \ tim.niven.KJRG \ Documents \ Visual Studio 2010 \项目\ TPS-干线\ TPS \ TPS \区\ CLIENTS \ \控制器AdjustmentProcessController.cs:行 257在lambda_method(Closure,ControllerBase,Object [])at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext,IDictionary2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary
2 参数)at System.Web.Mvc.ControllerActionInvoker<> c__DisplayClass15.b__12() 在 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter,ActionExecutingContext preContext,Func1 continuation) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList
1个过滤器,ActionDescriptor actionDescriptor, IDictionary`2参数)at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext,String actionName)
所以我整天都在用桌子敲打我的头 - 任何帮助或指导将不胜感激。
干杯,
添
答案 0 :(得分:1)
最终它很愚蠢(因为它经常是这样):它当然是动作中的其他一些代码,其中一个适配器方法是操作从数据库中检索到的对象,它不应该是
一旦我隔离了抛出异常的代码,并且它起了作用,我改变了事物的顺序,发现异常不是在AssetOwner的插入上抛出的。因此,我在整个代码中的多个位置调用了DataContext.SubmitChanges(),以找出导致问题的位置 - 找到并修复。