C# 将FlagsAttribute解析为SqlParameter的枚举
我有一个带有Flags属性的枚举C# 将FlagsAttribute解析为SqlParameter的枚举,c#,sql,sql-server,stored-procedures,enums,C#,Sql,Sql Server,Stored Procedures,Enums,我有一个带有Flags属性的枚举 [Flags] public enum AlcoholStatus { NotRecorded = 1, Drinker = 2, NonDrinker = 4 } 我正在创建一个Sqlparameter,如下所示 new SqlParameter("@AlcoholStatus", SqlDbType.VarChar) {Value = (int) AlcoholStatus} 如
[Flags]
public enum AlcoholStatus
{
NotRecorded = 1,
Drinker = 2,
NonDrinker = 4
}
我正在创建一个Sqlparameter,如下所示
new SqlParameter("@AlcoholStatus", SqlDbType.VarChar) {Value = (int) AlcoholStatus}
如果酒精状态包含所有值(NotRecorded | Drinker | NonDrinker),则返回7作为SqlParameter的值
我正在为一个存储过程解析这个参数,我更喜欢将值解析为“1,2,3”。最好的方法是什么
或者有没有其他简单的方法通过将整数值7解析到存储过程来过滤记录
编辑:这发生在一个过滤器中,用户希望看到具有上述任何状态的人。
这是一个相当复杂的sql查询。在那里,我过滤状态如下
WHERE AlcoholStatus IN "1,2,4,"
首先,我对sequel服务器知之甚少。。。但是 您是指虚构的“客户机”类(而不是枚举类型ALCOLDSTATUS)的属性
新SqlParameter(@ALCOLDSTATUS),SqlDbType.VarChar){Value=(int)client.ALCOLDSTATUS}
而且我倾向于认为“二进制标志”字段将“自然”存储在整数字段中。。。可能是一个没有签名的。瓦查尔似乎是个奇怪的选择 如果我理解正确,您正在尝试筛选某些场景,例如,您可以对where使用位操作,例如,从MyTable中选择*,其中酒精状态&0x3将同时选择未记录和饮用者。您还可以通过使用一系列CASE when组合一个存储过程,将AlcoholStatus转换为类似于1、2、3的字符串。如果您在WHERE子句中开始并输入值,您可以将7传递给存储过程,并告别AlcoholStatus列上的索引可能带来的任何好处 如果您需要建立一个ID字符串,下面的内容可能就是您想要的。根据需要进行优化-例如,我没有考虑到枚举中只有三个标志 如果在构建语句时在SQL中摆弄字符串,还需要注意SQL注入
string values = "";
for(int i = 0; i < 30; ++i) {
if((((int)AlcoholStatus) & (1 << i)) != 0) {
if(values != "") {
values += ",";
}
values += (i + 1).ToString();
}
}
字符串值=”;
对于(int i=0;i<30;++i){
if(((int)status)和(1忽略该枚举作为[Flags]是否有意义
,在我看来,存储此数据的唯一合理方法是在int
列中。只需存储值,不需要其他任何东西。试图将其强制为varchar
是错误的。数据库的工作是存储数据,而不是关心表示
如果需要按此进行筛选,则可以在搜索中使用位运算符,但请注意,在按组合进行搜索时(而不是通过等式,后者可以使用非聚集索引),性能会受到影响如果需要搜索任意组合,则考虑非正规化。如果只需要搜索可预测的位,那么可以用计算的持久化索引列将这些提升出来,也就是说,可以有一个自动<代码> IsDrinker < /Cuth>列(<代码>位< /代码>)。这表示第2位。我在下面编写了一个方法来获取逗号分隔的枚举ID,以便将其解析到数据库中
private static string GetAlcoholStatuses(Enums.Enums.AlcoholStatus? alcoholStatus)
{
if (alcoholStatus == null)
return string.Empty;
Enums.Enums.AlcoholStatus alcoholStatusValue = alcoholStatus.Value;
string alcoholStatuses = string.Empty;
if (alcoholStatusValue.HasFlag(Enums.Enums.AlcoholStatus.Drinker))
{
alcoholStatuses = string.Format("{0}{1}{2}", alcoholStatuses, (int)Enums.Enums.AlcoholStatus.Drinker, ",");
}
if (alcoholStatusValue.HasFlag(Enums.Enums.AlcoholStatus.NonDrinker))
{
alcoholStatuses = string.Format("{0}{1}{2}", alcoholStatuses, (int)Enums.Enums.AlcoholStatus.NonDrinker, ",");
}
if (alcoholStatusValue.HasFlag(Enums.Enums.AlcoholStatus.NotRecorded))
{
alcoholStatuses = string.Format("{0}{1}{2}", alcoholStatuses, (int)Enums.Enums.AlcoholStatus.NotRecorded, ",");
}
return alcoholStatuses;
}
但这永远不会发生,对吧(不记录|饮酒者|不饮酒者)它们是相互排斥的,所以为什么不重写枚举,使其分别具有1、2和3的整数值呢?也许如果你拒绝或分裂人格,它可能是2+4?(我假设2+3是OP的输入错误)@布拉德:我正在尝试做一个过滤器。所以,这些是复选框,用户可以选择其中的三个或两个。在这种情况下,即使它们通常是互斥的,也会发生这种情况。