C# 将标志拆分为规范化表
我有一张看起来像的桌子C# 将标志拆分为规范化表,c#,linq,linq-to-entities,linqpad,C#,Linq,Linq To Entities,Linqpad,我有一张看起来像的桌子 OldThing id | Value | Flags | ... int | varchar | int | ... ... | ... | 2 | ... ... | ... | 19 | ... ... | ... | 82 | ... ... | ... | 3 | ... ... | ... | 19 | ... ... | ... | 3 | .
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
在应用程序中被检查并生成为应用程序中定义的按位常量值
我正在尝试使用以下三个表来改进、更规范化的数据库:
Thing
id | Value | ...
int | varchar |
FlagDetail
id | description | mask
int | varchar | int
Flag
ThingID | FlagID
int | int
我尝试使用带有自定义IEqualityComparer
的Join
生成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;
}
}
这些表在多个应用程序中使用,因此迁移将是渐进的,同时添加额外的flagdail
行
是否有一种方法可以在Linq中生成标志
值,而不必手动写入循环?我想要的东西可以在迁移每个应用程序时在LinqPad中快速轻松地输入和运行
我目前有
FlagDetail
行,其掩码值为1
、2
和4
,除非我误解了,否则您需要做的是交叉连接,而不是正常连接
像这样,
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};
假设您在旧事物中有3行
1,'blah1',12,'blah2',2
3,'blah3',3 和
标记详细信息中的2行
1,'mask1',1
2,'mask2',2
您的加入将为您提供这一点,标志
1,1
2,2
3,1
有了我的问题,你就有了
1,1
2,2
3,1
3,2
我不确定我是否理解你,但是。。。是否要将oldsthings
与FlagDetails
合并?我说得对吗?您尝试了什么?我正在尝试使用flagdail.Mask
的值为Flag
表生成行,因此在(OldThing.Flags&flagdail.Mask)>0
时生成Flag
行。我只是想知道在Linq中是否有一种方法可以做到这一点,但我没有。@MaciejLos经过编辑以包含以前的尝试。您能给我们提供OldThings flags列内容和new flag mask列内容吗?不需要身份证或身份证text@Fredou被编辑以包括的数量。
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};