C# 如何使用ASP.NET MVC在数据库中存储多个复选框值
我正在开发一个使用ASP MVC和存储过程(SQL Server)的项目,我想在数据库中存储复选框项。我试图在模型中添加一个C# 如何使用ASP.NET MVC在数据库中存储多个复选框值,c#,sql-server,asp.net-mvc,stored-procedures,C#,Sql Server,Asp.net Mvc,Stored Procedures,我正在开发一个使用ASP MVC和存储过程(SQL Server)的项目,我想在数据库中存储复选框项。我试图在模型中添加一个列表类型,以便访问这些值,然后将它们存储在数据库中 问题在于,关系数据库是专门为每行/列组合存储一个值而设计的。为了存储多个值,我必须将列表序列化为单个值进行存储,然后在检索时对其进行反序列化 这是我的视图标记: <h6>Items</h6> <ul>
列表
类型,以便访问这些值,然后将它们存储在数据库中
问题在于,关系数据库是专门为每行/列组合存储一个值而设计的。为了存储多个值,我必须将列表序列化为单个值进行存储,然后在检索时对其进行反序列化
这是我的视图标记:
<h6>Items</h6>
<ul>
<li>
<label class="anim">
<input type="checkbox" class="checkbox" value="Soups" name="Items">
<span>Soups</span>
</label>
</li>
<li>
<label class="anim">
<input type="checkbox" class="checkbox" value="Burger" name="Items" >
<span>Burger</span>
</label>
</li>
<li>
<label class="anim">
<input type="checkbox" class="checkbox" value="Drinks" name="Items">
<span>Drinks</span>
</label>
</li>
<li>
<label class="anim">
<input type="checkbox" class="checkbox" value="Desserts" name="Items">
<span>Desserts</span>
</label>
</li>
</ul>
型号:
public List<string> Items { get; set; }
公共列表项{get;set;}
您不应该序列化/反序列化。这将是痛苦的使用后
假设您需要检索选中项目1和项目5的对象。
如果它被序列化为一个字符串,那么按如下方式存储它的效率和容易性就会降低
假设您有一个“Person”表,您想查看他们拥有的“Consoles”列表
您将有tableperson:
- id int主键
- 名称varchar不为空
- id int主键
- 名称varchar不为空
- id int主键
- person_id int(外键=>person(id))
- 控制台id int(外键=>控制台(id))
- (1) 托马斯
- (2) 皮埃尔
- (1) NES
- (2) MegaDrive
- (3) 新地理
- (1) (一)
- (1) (二)
- (1) (三)
- (2) (一)
- (2) (一)
SELECT *
FROM person p
INNER JOIN owned_console oc
ON p.id = oc.person_id
WHERE oc.console_id IN (3,1);
标志枚举-
[Flags]
public enum ItemStorage
{
Soups = 1,
Burger = 2,
Drinks = 4,
Dessert = 8,
Cheese = 16
}
我添加奶酪只是为了强调Flags枚举的二进制性质
这是你的另一个密码-
public class Stuff
{
private List<string> Items;
private static string Connection()
{
return ConfigurationManager.ConnectionStrings["deliverycon"].ToString();
}
public bool DoStuff()
{
try
{
using (SqlConnection con = new SqlConnection(Connection()))
{
using (SqlCommand cmd = new SqlCommand("AddNewBestellung", con))
{
cmd.Parameters.AddWithValue("@Items", (int)ConstuctEnumValueFromList(Items));
//other saved parameters...
con.Open();
int i = cmd.ExecuteNonQuery();
con.Close();
if (i >= 1)
return true;
else
return false;
}
}
}
catch (Exception ex)
{
string e = ex.Message;
return false;
}
}
private ItemStorage ConstuctEnumValueFromList(List<string> list)
{
var result = new ItemStorage();
if (list.Any())
{
var separatedList = string.join(",", list)
bool success = Enum.TryParse<ItemStorage>(separatedList, out result)
}
return result;
}
}
这应该给你
“汤、汉堡、饮料、甜点” XML序列化
首先,确保您熟悉。此方法要求将Items集合存储到SQL Server中的XML列中。它还有一个优点,就是您可以查询该列,只要您不怕SQLXML和XPath。许多开发人员都是这样
一旦你有了它,一切看起来都非常相似(如果简单一点的话)
公共类的东西
{
私人清单项目;
私有静态字符串连接()
{
返回ConfigurationManager.ConnectionString[“deliverycon”].ToString();
}
公共图书馆
{
尝试
{
使用(SqlConnection con=newsqlconnection(Connection()))
{
使用(SqlCommand cmd=newsqlcommand(“AddNewBestellung”,con))
{
cmd.Parameters.AddWithValue(“@Items”,ConstructXmlFromList(Items));
//其他保存的参数。。。
con.Open();
int i=cmd.ExecuteNonQuery();
con.Close();
如果(i>=1)
返回true;
其他的
返回false;
}
}
}
捕获(例外情况除外)
{
字符串e=例如消息;
返回false;
}
}
公共静态T FromXML(字符串xml)
{
使用(var stringReader=newstringreader(xml))
{
var serializer=newxmlserializer(typeof(T));
返回(T)序列化程序。反序列化(stringReader);
}
}
公共字符串ToXML(T obj)
{
使用(var stringWriter=new stringWriter(new StringBuilder()))
{
var xmlSerializer=新的xmlSerializer(typeof(T));
Serialize(stringWriter,obj);
返回stringWriter.ToString();
}
}
私有字符串构造函数XmlFromList(列表列表)
{
返回ToXML(列表);
}
}
同样,很容易将XML片段重新水化到您开始使用的列表中。你只要使用
var myList = FromXML<List<string>>(fieldValue);
var myList=FromXML(fieldValue);
实际上,您可以尝试使用标志枚举,因为您使用的是SQL Server,您还可以将复选框值数组存储为XML。SQL呢datatype@RichBryant谢谢,但你能解释一下吗,我会把这两个选项都做为答案,你可以试试。谢谢,但创建新表很复杂,我只想在一列中存储多个选项,我不同意,这很简单。见其他答案。接下来,我将序列化为XML,这样您就可以看到这是多么容易了。@Exact:这是正确的、关系式的处理方式。永远不要在一个单元格中存储多个值,只要说不就行了!要在单元格中用逗号分隔值,您将看到一场维护噩梦!从一开始就正确地做@Thomas:-在ANSI-92 SQL标准(25年前!)中,用正确的ANSIJOIN
语法替换了老式的逗号分隔的表列表样式,并且它的使用非常方便discouraged@Exact:存储多个值的正确关系方式是一个单独的表(每个值一行),用于处理“多个值”对于单个实体,谢谢,我必须在model?中编写Flags枚举,或者仅仅是一个整数值。任何一个都可以。好的,我会根据您的建议尝试让您知道,当我检查超过1个值时,只有第一个检查的值存储在数据库中,这很有趣。尝试在ConstructEnumValueFromList(List List)方法中放置断点并单步执行。
int i = 1 + 2 + 4 + 8;
var items = (ItemStorage)i;
Console.WriteLine(items.ToString());
public class Stuff
{
private List<string> Items;
private static string Connection()
{
return ConfigurationManager.ConnectionStrings["deliverycon"].ToString();
}
public bool DoStuff()
{
try
{
using (SqlConnection con = new SqlConnection(Connection()))
{
using (SqlCommand cmd = new SqlCommand("AddNewBestellung", con))
{
cmd.Parameters.AddWithValue("@Items", ConstructXmlFromList(Items));
//other saved parameters...
con.Open();
int i = cmd.ExecuteNonQuery();
con.Close();
if (i >= 1)
return true;
else
return false;
}
}
}
catch (Exception ex)
{
string e = ex.Message;
return false;
}
}
public static T FromXML<T>(string xml)
{
using (var stringReader = new StringReader(xml))
{
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(stringReader);
}
}
public string ToXML<T>(T obj)
{
using (var stringWriter = new StringWriter(new StringBuilder()))
{
var xmlSerializer = new XmlSerializer(typeof(T));
xmlSerializer.Serialize(stringWriter, obj);
return stringWriter.ToString();
}
}
private string ConstructXmlFromList(List<string> list)
{
return ToXML(list);
}
}
var myList = FromXML<List<string>>(fieldValue);