我有一张类似
的表格OldThing
id | Value | Flags | ...
int | varchar | int | ...
... | ... | 2 | ...
... | ... | 19 | ...
... | ... | 82 | ...
... | ... | 3 | ...
... | ... | 19 | ...
... | ... | 3 | ...
... | ... | 18 | ...
... | ... | 3 | ...
... | ... | 55 | ...
... | ... | 3 | ...
... | ... | 16 | ...
... | ... | 16 | ...
... | ... | 16 | ...
... | ... | 16 | ...
... | ... | 16 | ...
... | ... | 16 | ...
... | ... | 112 | ...
... | ... | 3 | ...
... | ... | 3 | ...
... | ... | 3 | ...
... | ... | 48 | ...
... | ... | 16 | ...
... | ... | 16 | ...
... | ... | 64 | ...
... | ... | -1 | ...
... | ... | 3 | ...
其中OldThing.Flags
在应用程序中检查并生成为app中定义的按位和常量值。
我尝试使用以下三个表格转移到改进的,更加规范化的数据库:
Thing
id | Value | ...
int | varchar |
FlagDetail
id | description | mask
int | varchar | int
Flag
ThingID | FlagID
int | int
我尝试使用Join
使用自定义IEqualityComparer
生成FlagDetail表的值,但它返回的结果很少我想要的结果:
void Main()
{
var flags = OldThings
.ToArray()
.Join(FlagDetails, thing=>thing.Flags.Value,
flag => flag.Mask, (t,f) => new {t, f},
new BitwiseComparer())
.Select (r => new Flag{ThingID = r.t.Id, FlagId = r.f.Id});
Flags.InsertOnSubmit(flags);
SubmitChanges();
}
// Define other methods and classes here
class BitwiseComparer : IEqualityComparer<int>
{
public bool Equals(int a, int b)
{
return (a&b)>0;
}
public int GetHashCode(int n)
{
return 0;
}
}
这导致19个结果,而预期的行数应为29(由SubscriptionTypes.Sum(st => EmailNames.Count(n => (n.Subscriptions & st.Mask)>0));
计算)。
最后,我使用了两个嵌套的foreach
循环:
var flags = new List<Flag>();
foreach (var thing in OldThings)
{
foreach (var flag in FlagDetails)
{
if ((thing.Flag & flag.Mask) > 0)
subs.Add(new Flag{ThingId = Thing.Id, FlagId = flag.Id});
}
}
Flags.InsertAllOnSubmit(flags);
SubmitChanges();
这些表在多个应用程序中使用,因此迁移将逐步进行,并在我们开始时添加额外的FlagDetail
行。
有没有办法在Linq中生成flags
值,而无需手动编写循环?我可以在迁移每个应用程序后快速轻松地在LinqPad中输入和运行。
我目前有FlagDetail
行,其掩码值为1
,2
和4
。
答案 0 :(得分:2)
除非我误解,你需要做的是交叉连接而不是正常连接
像这样;var flags = from o in OldThings.ToArray()
from f in FlagDetails
where (o.Flags.Value & flag.Mask) > 0
select new Flag{ThingID = o.Id, FlagId = f.Id};
假设您在OldThings
;
1,&#39; blah1&#39;,1
2,&#39; blah2&#39;,2
3,&#39; blah3&#39;,3
和FlagDetails
中的第2行;
1,&#39; mask1&#39;,1
2,&#39; mask2&#39;,2
您的加入会为您提供Flag
;
1,1 2,2 3,1
我的查询你将有
1,1 2,2 3,1 3,2