假设我们有两个表具有多对多关系:
public class Left{ /**/ }
public class Right{ /**/ }
public class LeftRight{ /**/ }
以下内容足以解开这些记录(忽略不止一个关系或未定义关系的可能性)吗?
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();
}
还是我必须在两个部分上都做?这里需要什么?
最佳答案
这是我为简化此问题而编写的“小”扩展方法:
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);
}
}
}
可能可以改进,但是对我有用:)
例:
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是中间表。
这将为您提供:
class A { EntitySet<B> Bs {get;} }
class B { EntitySet<A> As {get;} }
class AB { B B {get;} A A {get;} }
现在,您有了一个对象A,该对象通过AB引用了多个B。
通过“ fkvalue”从A.B中获取所有B。
获取添加的内容。
获取已删除的内容。
添加所有新的,并通过“ fkmaker”构建AB。
删除所有已删除的。
(可选)通过“ fkdelete”删除其他引用的对象。
我想通过改用Expression来改进此方法,因此我可以更好地“模板化”该方法,但效果相同。
关于linq-to-sql - 通过linq to sql删除多对多关系的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1182895/