Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将FlagsAttribute解析为SqlParameter的枚举_C#_Sql_Sql Server_Stored Procedures_Enums - Fatal编程技术网

C# 将FlagsAttribute解析为SqlParameter的枚举

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属性的枚举

  [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的输入错误)@布拉德:我正在尝试做一个过滤器。所以,这些是复选框,用户可以选择其中的三个或两个。在这种情况下,即使它们通常是互斥的,也会发生这种情况。