ASP.NET C#实体框架 - 如何正确更新外键? [英] ASP.NET C# Entity Framework - How to update Foreign Key properly?

查看:201
本文介绍了ASP.NET C#实体框架 - 如何正确更新外键?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对这个EF很新,但我觉得我有进步。无论如何,看来我不知道如何通过外键更新一个相关的对象。



我的DbRelation是:



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

  public class ManagerBase 
{
private static NoxonEntities _entities = null;

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

return _entities;
}
}
}

我有很多东西试过。这是一个:



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;
//或
Mem.LanguageId = Lang.Id;
currentMemberManager.Save(Mem);

在...中,我收到一个错误,如

 对数据库的更改已成功提交,但更新对象上下文时发生错误。 ObjectContext可能处于不一致的状态。内部异常消息:发生参照完整性约束违例:定义参照约束的属性值在关系中的主体和从属对象之间不一致。 

2)

 code> //管理器使用ManagerBase类作为基类
MemberManager currentMemberManager = new MemberManager();
currentMemberManager.Save(Globals.CurrentMember.Id,Globals.CurrentLanguage.Id);
//这些来自Http会话的全局对象
//你也可以说不要把整个成员对象保存在会话中,我不会在这个结束之后出来

这是我的SAVE方法,我有实际的问题:

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

在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();
}
}

错误是

 对象引用未设置为对象的实例。 

显然我与EF错误的方式。



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



非常感谢你。

解决方案

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



如果没有,那么对象图继续成长直到应用程序池最终耗尽,加上并发访问可以遇到各种问题。静态对象在所有线程之间共享,所以想象如果两个用户同时使用你的应用程序,他们都将使用相同的数据上下文,并且会相互影响。



其次,您正在使用一个单身,这是最受谴责的模式之一,原因很多。他们有他们的用途,但是比大多数人使用它们更罕见。



第三,基于错误消息,这听起来像你的数据模型可能不是与您的EF模型同步,因此它变得困惑和抛出异常。您是否更改了数据库结构,而无需更新ef模型?请记住,重新生成并不总是更新所有内容,有时您必须手动更新,或删除对象并重新添加。



第四,您的真正的问题(相信我,我已经提出的那些也是真正的问题,那么在某些时候,你会在后面咬你)就在于这个代码:

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

你必须意识到的第一件事是,EF返回跟踪的对象,这些对象在EF中有引用并跟踪发生的变化。你在这里做的是获取一个对象,然后将其丢弃,并将其替换为传入的非跟踪对象。



您必须更新对象从第一种方法返回,而不是用新的方法替换。


I'M quite new to this EF but I think I'M making progress. Anyway, it appears I do NOT know how to Update an object that is RELATED by a Foreign Key.

My DbRelation is:

And I'm trying to UPDATE the one members LANGUAGEID and here is the Context I invoke:

public class ManagerBase
    {
        private static NoxonEntities _entities = null;

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

                return _entities;
            }
        }
    }

There are many things I have tried. Here is one:

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);

In appreach 1, I get an error like

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.

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();
                    }
                }
            }

In appreach 1, I get an error in this code in EF model edmx file

[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();
            }
        }

And the error is

Object reference not set to an instance of an object.

Clearly I'm in the wrong way with EF.

Could you please help me and show how to properly Update a relation Id (ForeignKeyId) ?

Thank you so much.

解决方案

Yes, you are using EF in many wrong ways. First, as Arran points out, you should never make your data context static. I know that seems easier, but it's a huge problem because data contexts are designed to be created and destroyed frequently.

If you don't, then the object graph continues to grow until the app pool is eventually exhausted, plus you can run into all kinds of problems with concurrent access. Static objects are shared between all threads, so imagine if two users are using your app at the same time, they will both be using the same data context and would stomp all over each other.

Second, you're using a singleton, which is one of the most reviled patterns there are, for a lot of reasons. They have their uses, but they're far more rare than most people use them.

Third, based on the error messages, it sounds like your data model may not be in sync with your EF model, and thus it's getting confused and throwing exceptions. Have you made changes to your database structure without updating your ef model? Bear in mind that regenerating doesn't always update everything, and sometimes you have to either update it manually, or delete your objects and re-add them.

Fourth, your real problem (trust me, the ones I've laid out are also real problems, that WILL bite you in the rear at some point) lies in this code:

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

The first thing you have to realize is that EF returns tracked objects, these objects have references in EF and track the changes that occur. What you are doing here is getting an object, and then throwing it away and replacing it with a non-tracked object that was passed in.

You have to update the object returned from the First method, and not replace it with a new one.

这篇关于ASP.NET C#实体框架 - 如何正确更新外键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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