• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
adow
博客园    首页    新随笔    联系   管理    订阅  订阅
linq to sql 的更新问题(分层和多表关系时)

这个诡异的问题搞了我一天才解决,我用ling to sql 来操作两张表,一张是tb_mail_sender,tb_mail_receiver,tb_mail_receiver.mailid作为外键和tb_mail_sender.id进行一对多关联。我建立实体后两个表分别对应:

CMailSender,CMailReceiver:

我们都看到网络上用于示例的文章都是基于同一个datecontext的,但是在大部分项目中,因为分层的关系,我们要将一个实体在外部修改后传入,然后再进行更新。在这样的情况下,我们需要用attache方法来把这个对象附加到,否则就会得到一个异常大概是说对象是另一个datacontext的。

一般我们的代码:

public bool DeleteMailSender(CMailSender sender)
        {
            TestdbDataContext db = null;
            db = new TestdbDataContext();
            db.CMailSenders.Attach(sender, true);       
            db.CMailSenders.DeleteOnSubmit(sender);
            db.SubmitChanges();
            return true;
        }

在大部分情况下可能不会有问题,但是当我们使用了表的关系之后,问题就产生了,

CMailSender有一个MailReceivers来引用左右的子表的相关数据,CMailReceiver有一个CMailSender来引用父表的一条数据。

这时,我们就能遇到那个最诡异的问题:

An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext.  This is not supported.

我们想删除父表的一条数据,而且字表没有对应的行,理论上是可行的,但是却出现了这个异常,而且是发生在attache方法中。

同样的方法,当我们想删除子表的一条数据时,同样:

public bool DeleteMailReceiver(CMailReceiver receiver)
        {
            using (TestdbDataContext db = new TestdbDataContext())
            {
                StreamWriter sw = new StreamWriter("E:\\test\\testlinq\\webs\\log.txt", true); // Append
                db.Log = sw;

                                db.CMailReceivers.Attach(receiver, true);
                              db.CMailReceivers.DeleteOnSubmit(receiver);
                db.SubmitChanges();
                sw.Close();
                return true;
            }
        }

一样的出错提示。

我为了这个问题大概浪费了大半天时间,最后我在国外 blog 上找到了解决方法,在attache之前先把关联取消。所以我扩展了那两个实体类,然后创建Detach方法:

public partial class CMailReceiver
    {
        public void Detach()
        {
            this._CMailSender = default(EntityRef<CMailSender>);
        }
    }
    public partial class CMailSender
    {
        public void Detach()
        {
            this.CMailReceivers = default(EntitySet<CMailReceiver>);
        }
    }

再来用:

public bool DeleteMailSender(CMailSender sender)
        {
            TestdbDataContext db = null;
            db = new TestdbDataContext();
            sender.Detach();//////就是这个
            db.CMailSenders.Attach(sender, true);       
            db.CMailSenders.DeleteOnSubmit(sender);
            db.SubmitChanges();
            return true;
        }

还真的就正常了,好像就是发生在两个对象存在外键关联的情况下会发生这个问题。

我总感觉这样会出现点问题,因为好像取消了关系。

posted on 2008-05-13 16:24  adow  阅读(1935)  评论(2)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3