由于一个或多个外键属性不可为空,因此无法更改该关系。 (2) [英] The relationship could not be changed because one or more of the foreign-key properties is non-nullable. (2)

查看:79
本文介绍了由于一个或多个外键属性不可为空,因此无法更改该关系。 (2)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在.NET 4.5应用程序中使用Entity Framework 6.1.3,该程序具有Code First和Oracle数据库服务器上的手工表架构。大多数事情都正常。对于新功能, SaveChanges 会引发以下异常:

I'm using Entity Framework 6.1.3 in a .NET 4.5 application with Code First and a hand-crafted table schema on an Oracle database server. Most things work fine. For a new function the following exception is thrown in SaveChanges:


操作失败:由于一个或多个外键属性不可为空,因此无法更改该关系。对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

堆栈跟踪:


  • System.Data.Entity.Core.Objects.ObjectContext。 PrepareToSaveChanges(System.Data.Entity.Core.Objects.SaveOptions)

  • System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(System.Data.Entity.Core.Objects.SaveOptions ,bool)

  • System.Data.Entity.Internal.InternalContext.SaveChanges()

  • (我的代码)

  • System.Data.Entity.Core.Objects.ObjectContext.PrepareToSaveChanges(System.Data.Entity.Core.Objects.SaveOptions)
  • System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(System.Data.Entity.Core.Objects.SaveOptions, bool)
  • System.Data.Entity.Internal.InternalContext.SaveChanges()
  • (my code)

它什么也没说。它对我找不到帮助。 SQL日志为空,所以我猜想甚至在尝试访问数据库之前,EF本地都已检测到该问题。

It says nothing about the problem. It doesn't help me to find it. The SQL log is empty so I guess the problem was detected by EF locally before even trying to reach out to the database.

我的问题是:我怎么能调试这个东西吗?有关哪个对象中的哪个外键具有哪个值但不应该具有它的详细信息在哪里?

My question is: How can I debug this thing? Where's the details about which foreign key in which object has which value but shouldn't have it? Are there trace logs available for Entity Framework that contain internal data about what was done?

情况是否太复杂了,无法在此处显示,所以请不要提出要求。我想帮助自己,我只需要坚持。

The situation is way too complex to show it here so please don't ask for it. I want to help myself out of this, I just need assistence with that.

推荐答案

您可以登录SQL

using (var context = new BlogContext())
{
    context.Database.Log = Console.Write;

    // Your code here...
}

您甚至可以制作这样的自定义日志格式化程序

Even more you can make a custom log formatter like this

public class OneLineFormatter : DatabaseLogFormatter
{
    public OneLineFormatter(DbContext context, Action<string> writeAction)
        : base(context, writeAction)
    {
    }

    public override void LogCommand<TResult>(
        DbCommand command, DbCommandInterceptionContext<TResult> interceptionContext)
    {
        Write(string.Format(
            "Context '{0}' is executing command '{1}'{2}",
            Context.GetType().Name,
            command.CommandText.Replace(Environment.NewLine, ""),
            Environment.NewLine));
    }

    public override void LogResult<TResult>(
        DbCommand command, DbCommandInterceptionContext<TResult> interceptionContext)
    {
    }
}

您可以使用自己的日志格式化程序截取确切的异常,假设它是'DbEntityValidationException'

You can intercept the exact exception by your own log formatter for that exact exception assuming it is 'DbEntityValidationException'

public class MyExcpetionCommandInterceptor : IDbCommandInterceptor
{


    public void NonQueryExecuting(
        DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
        LogIfNonAsync(command, interceptionContext);
    }

    public void NonQueryExecuted(
        DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
        LogIfError(command, interceptionContext);
    }

    public void ReaderExecuting(
        DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
        LogIfNonAsync(command, interceptionContext);
    }

    public void ReaderExecuted(
        DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
        LogIfError(command, interceptionContext);
    }

    public void ScalarExecuting(
        DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
        LogIfNonAsync(command, interceptionContext);
    }

    public void ScalarExecuted(
        DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
        LogIfError(command, interceptionContext);
    }

    private void LogIfNonAsync<TResult>(
        DbCommand command, DbCommandInterceptionContext<TResult> interceptionContext)
    {
        if (!interceptionContext.IsAsync)
        {
            Logger.Warn("Non-async command used: {0}", command.CommandText);
        }
    }

    private void LogIfError<TResult>(
        DbCommand command, DbCommandInterceptionContext<TResult> interceptionContext)
    {
        if (interceptionContext.Exception.GetType() == typeof(DbEntityValidationException) || typeof(DbEntityValidationException).IsAssignableFrom(interceptionContext.Exception.GetType()) )
        {
            Logger.Error("Command {0} failed with exception {1}",
                command.CommandText, interceptionContext.Exception);
        }
    }
}

有一篇不错的文章Microsoft 记录和拦截数据库操作

There is a nice article about that in Microsoft Logging and intercepting database operations

这篇关于由于一个或多个外键属性不可为空,因此无法更改该关系。 (2)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆