使用Linq,尝试选择不在我本地集中的所有记录失败:
var localset = new List<Category>();
localset.Add( new Category { pk1 = 1, pk2 = 1, name = "one" } );
localset.Add( new Category { pk1 = 1, pk2 = 2, name = "two" } );
var dbCategories = dc.Categories;
var diff = dbCategories.Except(localset);
我需要做基本的CRUD:当不在我的本地集中时从数据库集中删除,更新存在的位置,并在不存在时添加新的。
我通常会这样做:
delete from Category C where not exists
( select null from LocalSet L where C.pk1 = L.pk1 and C.pk2 = L.pk2 )
update Category set name = L.name
from LocalSet L
where L.pk1 = Category.pk1 and L.pk2 = Category.pk2
insert into Category (pk1, pk2, name)
select pk1, pk2, name
from LocalSet L
where not exists (
select null from Category C where L.pk1 = C.pk1 and L.pk2 = C.pk2 )
我想的很容易。但是,.Contains似乎是唯一适用于本地集的方法,它似乎只比较单个字段。数据库表有复合键。
如果不更改复合键,有没有办法完成这些任务?
答案 0 :(得分:1)
我不清楚你正在谈论哪种Contains方法,我担心......但使用复合键的通用解决方案是使用匿名类型创建单个值。
例如,如果要在复合键上加入,可以使用
from x in xs
join y in ys on new { x.k1, x.k2 } equals new { y.k1, y.k2 }
这有帮助吗?
答案 1 :(得分:1)
这样做:
var localset = new List<Category>();
localset.Add(new Category { pk1 = 1, pk2 = 1, name = "one" });
localset.Add(new Category { pk1 = 1, pk2 = 2, name = "two" });
var flattened = localset
.Select(dd => dd.pk1 + "|" + dd.pk2 + "|" + dd.name)
.ToArray();
var dbCategories = dc.Categories;
var diff = from c in dbCategories
let x = c.pk1 + "|" + c.pk2 + "|" + c.name
where !flattened.Contains(x)
select c;
这会将复合键转换为允许您使用Contains
运算符的单个数组。如果有帮助,请告诉我。欢呼声。
答案 2 :(得分:1)
您必须实施以下CategoryComparer
:
public class CategoryComparer : IEqualityComparer<Category>
{
public bool Equals(Category a, Category b)
{
bool result = false;
if( a.pk1 == b.pk1 && a.pk2 == b.pk2 && a.name == b.name)
result = true;
return result;
}
public int GetHashCode(Category category)
{
if (Object.ReferenceEquals(category, null)) return 0;
return category.pk1.GetHashCode() ^ category.pk2.GetHashCode();
}
}
然后调用Enumerable.Except:
var localset = new List<Category>();
localset.Add( new Category { pk1 = 1, pk2 = 1, name = "one" } );
localset.Add( new Category { pk1 = 1, pk2 = 2, name = "two" } );
var diff = dc.Categories
.AsEnumerable()
.Except(localset, new CategoryComparer());
请告诉我这是否能满足您的需求。