我有一个非常复杂的数据库模型。我的程序计算了一些data+db entries
和modifies+generates new entries
以更新并插入数据库中。
当我使用数据库上下文插入条目时,一切正常。但是当我尝试保存更改时:
{“操作失败:由于一个或多个外键属性不可为空,因此无法更改关系。对关系进行更改时,相关的外键属性设置为null如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。“}
关于这个主题,我在SO上看到了太多问题。但是我的问题是模型太复杂了,我无法跟踪问题。 Entity Framework 6没有提供有关问题来源,关系名称,...
的任何信息。是否有一种方法可以从Entity Framework获得更多帮助以找到问题的根源?
答案 0 :(得分:1)
您必须分析您的对象以解决此问题。
这里有一些简单的代码来说明您的Exception
:
static void Main()
{
using (MyDbContext ctx = new MyDbContext())
{
// Build a new object
MyClass o = new MyClass() { Id = 1, ChildObject = null };
// Add it to your Context (It's not in the DB yet!)
ctx.MyObjects.Add(o);
// Write all changes (the new object) to the Db
ctx.SaveChanges();
}
}
// You got some DbContext with a DbSet pointing to your Table "MyTable"
public class MyDbContext : DbContext
{
public DbSet<MyClass> MyObjects { get; set; }
}
// You've got a class to map your table to some nice object.
[Table("MyTable")]
public class MyClass
{
// Some column..
[Key]
public int Id { get; set; }
// And some ForeignKey! Which maps a column with the Id to an object.
[ForeignKey("ChildObjectId")]
public MyClass ChildObject { get; set; }
}
在此示例中,我创建了一个Context添加对象并保存更改(在表中创建一个Insert)。
第一:在SaveChanges发生异常,因为属性“ ChildObject”可以设置为null,因为我们对该属性没有任何限制。
2nd:异常是Db异常。您的程序(可能)运行正确。但是qour Db告诉您,不允许在MyTable中没有引用ChildObject的行。
您必须问自己是否配置数据库错误(使该列可为空),或者您的程序忘记设置子级。
希望您能看到:您必须深入研究代码。您的“完整模型”存在问题,必须解决。
考虑阅读上下文的SQL日志。示例:ctx.Log = Console.WriteLine;
(这里没有工作室,但我想我应该是这样的人。)
这样,您可以获取最后一个SQL查询并在Db上运行它,以获得更好的错误输出。
答案 1 :(得分:0)
发生问题是因为引用的表值直接与主表的c#对象内的主表相关联
CREATE TABLE [dbo].[MainTable](
[MainId] [int],
[Name] [varchar](50) NOT NULL
);
CREATE TABLE [dbo].[ReferedTable](
[ReferId] [int],
[MainId] [int] NOT NULL,
[Name] [varchar](50) NULL
);
外键有约束
using (EF context = new EF())
{
var values = context.MainTable.Include("ReferedTable");
var referedValues = values.ReferedTable.ToList();
foreach (var value in referedValues)
{
context.ReferedTable.DeleteObject(value);
}
context.SaveChanges();
}
如果您尝试执行以下操作,则会出现错误。因为ReferedTable已连接到主表,并且如果您对其进行了更改并保存,则EF会引发错误
using (EF context = new EF())
{
var values = context.MainTable.Include("ReferedTable");
var referedValues = values.ReferedTable.ToList();
foreach (var value in referedValues)
{
values.ReferedTable.Remove(value);
}
context.SaveChanges();
}
答案 2 :(得分:0)
我按照以下步骤手动递归地访问了对象的每个子对象:
if(parent.child!=null){
parent.childId=parent.child.id;
parent.child=null;
}
通过这种方式,您可以从父对象中删除每个子对象,而只保留ID,因此EntityFramework不会进行任何错误的插入,并且仍然确信存在这种关系。