ASP.NET C#Entity Framework - 如何正确更新外键?

E-A*_*E-A 1 c# asp.net entity-framework-4

我对这个EF很新,但我认为我正在取得进展.无论如何,似乎我不知道如何更新由外键关联的对象.

我的DbRelation是: 在此输入图像描述

我正在尝试更新一个成员LANGUAGEID,这是我调用的上下文:

public class ManagerBase
    {
        private static NoxonEntities _entities = null;

        public NoxonEntities Entities
        {
            get
            {
                if (_entities == null)
                    _entities = new NoxonEntities();

                return _entities;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

我尝试过很多东西.这是一个:

1)

MemberManager currentMemberManager = new MemberManager();
var Mem = currentMemberManager.MyEntities.Member.SingleOrDefault(c => c.Id == 2);
var Lang = currentLanguageManager.Entities.Language.SingleOrDefault(c => c.Id == 1);

            Mem.Language = Lang;
//Or
            Mem.LanguageId = Lang.Id;
currentMemberManager.Save(Mem);
Run Code Online (Sandbox Code Playgroud)

在appreach 1中,我得到一个错误

The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship.
Run Code Online (Sandbox Code Playgroud)

2)

//Managers uses ManagerBase class as a Base class
MemberManager currentMemberManager = new MemberManager();
currentMemberManager.Save(Globals.CurrentMember.Id, Globals.CurrentLanguage.Id);
//These Global objects coming from a Http Session
//You may also say not to keep whole member object in session which I'll not after I figure this out

Here is my SAVE method and where I have the actual problem:

public void Save(Member entity)
        {
            var Data = base.Entities.Member.First(c => c.Id == entity.Id);
                    if (Data != null)
                    {
                        Data = entity;
                        base.Entities.SaveChanges();
                    }
                }
            }
Run Code Online (Sandbox Code Playgroud)

在appreach 1中,我在EF模型edmx文件中的代码中出错

[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.Int32 LanguageId
        {
            get
            {
                return _LanguageId;
            }
            set
            {
                OnLanguageIdChanging(value);
                ReportPropertyChanging("LanguageId");
                _LanguageId = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("LanguageId");
                OnLanguageIdChanged();
            }
        }
Run Code Online (Sandbox Code Playgroud)

错误是

Object reference not set to an instance of an object.
Run Code Online (Sandbox Code Playgroud)

显然,我和EF的方式不对.

能否帮助我并展示如何正确更新关系ID(ForeignKeyId)?

非常感谢.

Eri*_*sch 6

是的,您正在以许多错误的方式使用EF.首先,正如Arran所指出的那样,您永远不应该使您的数据上下文保持静态.我知道这似乎更容易,但这是一个很大的问题,因为数据上下文的设计经常被创建和销毁.

如果不这样做,那么对象图将继续增长,直到应用程序池最终耗尽为止,此外,您可以遇到并发访问的各种问题.静态对象在所有线程之间共享,因此想象一下如果两个用户同时使用您的应用程序,它们将使用相同的数据上下文并且会相互踩踏.

其次,由于很多原因,你使用的是单身,这是最受辱骂的模式之一.它们有它们的用途,但它们比大多数人使用它们要少得多.

第三,基于错误消息,听起来您的数据模型可能与您的EF模型不同步,因此它变得混乱并抛出异常.您是否在不更新ef模型的情况下更改了数据库结构?请记住,重新生成并不总是更新所有内容,有时您必须手动更新它,或者删除对象并重新添加它们.

四,你真正的问题(相信我,我已经奠定了的人也是现实的问题,那WILL咬你在某一点后)就在于此代码:

var Data = base.Entities.Member.First(c => c.Id == entity.Id);
if (Data != null)
{
    Data = entity;
    base.Entities.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

您必须意识到的第一件事是EF返回跟踪对象,这些对象在EF中有引用并跟踪发生的更改.你在这里做的是获取一个对象,然后扔掉它并用传入的非跟踪对象替换它.

您必须更新从First方法返回的对象,而不是用新方法替换它.