通过linq to sql删除多对多关系的正确方法? [英] Correct way to remove a many-to-many relationship via linq to sql?

查看:67
本文介绍了通过linq to sql删除多对多关系的正确方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有两个具有多对多关系的表:

Let's say we have two tables with a many-to-many relationship:

public class Left{ /**/ }

public class Right{ /**/ }

public class LeftRight{ /**/ }

以下内容足以解开这些记录(忽略不止一个关系或未定义关系的可能性)吗?

is the following sufficient to unhook these records (ignore the possibility of more than one relationship or no relationship defined)?

public void Unhook(Left left, Right right){
  var relation = from x in Left.LeftRights where x.Right == right;
  left.LeftRrights.Remove(relation.First());
  Db.SubmitChanges();
}

还是我必须在两个部分上都做?这里需要什么?

Or do I have to do it on both parts? What's required here?

推荐答案

这是我为简化此问题而编写的小"扩展方法:

Here is a 'little' extension method I wrote to simplify this problem:

  public static class EntitySetExtensions
  {
    public static void UpdateReferences<FK, FKV>(
        this EntitySet<FK> refs,
        Func<FK, FKV> fkvalue,
        Func<FKV, FK> fkmaker,
        Action<FK> fkdelete,
        IEnumerable<FKV> values)
      where FK : class
      where FKV : class
    {
      var fks = refs.Select(fkvalue).ToList();
      var added = values.Except(fks);
      var removed = fks.Except(values);

      foreach (var add in added)
      {
        refs.Add(fkmaker(add));
      }

      foreach (var r in removed)
      {
        var res = refs.Single(x => fkvalue(x) == r);
        refs.Remove(res);
        fkdelete(res);
      }
    }
  }

它可能会有所改进,但对我有用:)

It could probably be improved, but it has served me well :)

示例:

Left entity = ...;
IEnumerable<Right> rights = ...;

entity.LeftRights.UpdateReferences(
 x => x.Right, // gets the value
 x => new LeftRight { Right = x }, // make reference
 x => { x.Right = null; }, // clear references
 rights);

算法描述:

假设A和B是多对多关系,其中AB是中间表.

Suppose A and B is many-to-many relationship, where AB would be the intermediary table.

这将为您提供:

class A { EntitySet<B> Bs {get;} }
class B { EntitySet<A> As {get;} }
class AB { B B {get;} A A {get;} }

您现在有了一个对象A,该对象通过AB引用了许多B.

You now have an object of A, that reference many B's via AB.

  1. 通过"fkvalue"从A.B中获取所有B.
  2. 获取添加的内容.
  3. 获取已删除的内容.
  4. 添加所有新内容,然后通过"fkmaker"构建AB.
  5. 删除所有已删除的内容.
  6. (可选)通过"fkdelete"删除其他引用的对象.

我想通过改用Expression来改善这一点,因此我可以更好地模板化"该方法,但其工作原理相同.

I would like to improve this by using Expression instead, so I could 'template' the method better, but it would work the same.

这篇关于通过linq to sql删除多对多关系的正确方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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