C# 使用Linq to SQL简化数组列的创建
我需要用未知大小的字符串、整数或其他数组创建SQL表。最好的方法是为它创建单独的表。像这样(下面是伪代码,我不知道我是否正确使用了“主键”): 公共类数据库:DataContext { 公共表用户{get{return GetTable();}} 公共表用户角色{get{return GetTable();}} } [附表] 公共类用户帐户 { [列(IsPrimaryKey=true)] 公共字符串用户名; [专栏] 公共字符串密码; } [附表] 公共类UserAccount\u角色 { [列(IsPrimaryKey=true)] 公共字符串用户名; [列(IsPrimaryKey=true,IsDbGenerated=true)] 公共国际罗莱德; [专栏] 公共价值; } 然而,这感觉很笨拙,因为如果我不担心SQL实现的话,UserAccount_角色可能只是UserAccount类中的简单“列表角色” 我宁愿这样做:C# 使用Linq to SQL简化数组列的创建,c#,sql,arrays,linq,linq-to-sql,C#,Sql,Arrays,Linq,Linq To Sql,我需要用未知大小的字符串、整数或其他数组创建SQL表。最好的方法是为它创建单独的表。像这样(下面是伪代码,我不知道我是否正确使用了“主键”): 公共类数据库:DataContext { 公共表用户{get{return GetTable();}} 公共表用户角色{get{return GetTable();}} } [附表] 公共类用户帐户 { [列(IsPrimaryKey=true)] 公共字符串用户名; [专栏] 公共字符串密码; } [附表] 公共类UserAccount\u角色 { [
public class DataBase : DataContext
{
public Table<UserAccount> users { get { return GetTable<UserAccount>(); } }
}
[Table]
public class UserAccount
{
[Column(IsPrimaryKey = true)]
public string username;
[Column]
public string password;
[MyColumn]
public MySQLList<DataBase, int> roles;
}
公共类数据库:DataContext
{
公共表用户{get{return GetTable();}}
}
[附表]
公共类用户帐户
{
[列(IsPrimaryKey=true)]
公共字符串用户名;
[专栏]
公共字符串密码;
[菌柱]
公共MySQLList角色;
}
我想做“类MySQLList:List
”。在数据库类(“B”)中,我使用了一些静态方法来授予对正确数据库的访问权。然后在MySQLList中,我通过重载的列表方法操作数据库。这将导致在“幕后”构建和访问表UserAccount_角色,因为程序员(主要是我)在自定义列表中看到的只是简化的解决方案
我的实际问题是:
如果您希望避免显式声明连接表,则可能更适合您。它将允许您直接创建多对多关系,而不需要中间类型 进一步阅读
建议使用Linq To SQL创建两个具有多对多关系的表:
[Table]
public class UserAccount
{
[Column(IsPrimaryKey = true)]
public string username;
[Column]
public string password;
private EntitySet<UserRole> _userRole;
[Association(Storage = "_userRole", OtherKey = "userName")]
public EntitySet<UserRole> UserRoles
{
get { return this._userRole; }
set { this._userRole.Assign(value); }
}
}
[Table]
public class Role
{
[Column(IsPrimaryKey = true)]
public int roleId;
[Column]
public string roleName;
private EntitySet<UserRole> _userRole;
[Association(Storage = "_userRole", OtherKey = "roleId")]
public EntitySet<UserRole> UserRoles
{
get { return this._userRole; }
set { this._userRole.Assign(value); }
}
}
[Table]
public class UserRole
{
[Column(IsPrimaryKey = true)]
public int roleId;
[Column(IsPrimaryKey = true)]
public string userName;
private EntityRef<Role> _role;
[Association(Storage = "_role", ThisKey = "userName")]
public EntitySet<Role> Role
{
get { return this._role.Entity; }
set { this._role.Assign(value); }
}
private EntityRef<UserAccount> _userAccount;
[Association(Storage = "_userAccount", ThisKey = "userName")]
public EntitySet<UserRole> UserAccount
{
get { return this._userAccount.Entity; }
set { this._userAccount.Assign(value); }
}
}
但是,您还可以做更多的事情,这对于序列化数组来说是不可能的
进一步阅读
如果您真的想在单个列中存储一个数组,恐怕在LINQtoSQL中没有标准的方法(可能一些第三方提供商会支持它)。您最好自己进行序列化,如下所示:
[Table]
public class UserAccount
{
...
[Column]
private string rawRoles;
public IEnumerable<int> Roles
{
get
{
return (this.rawRoles == null)
? return new int[0] :
: this.rawRoles.Split(",").Select(s => int.Parse(s));
}
set
{
this.rawRoles = (value == null)
? null
: String.Join(",", value);
}
}
}
[表格]
公共类用户帐户
{
...
[专栏]
私有字符串角色;
公共可数角色
{
得到
{
返回(this.rawRoles==null)
?返回新整数[0]:
:this.rawRoles.Split(“,”).Select(s=>int.Parse);
}
设置
{
this.rawRoles=(值==null)
无效的
:String.Join(“,”值);
}
}
}
当然,还有更好的序列化数据的方法,这只是一个例子。您不能在任何Linq to SQL查询中使用它,而且它的数据库设计非常糟糕-但是,嘿,至少它满足您的要求。使用EntitySet和EntityRef是一个很好的建议,我接受它。但是,我的主要问题是避免每次创建表中单向数据的简单列表时必须定义一个或两个附加表。我如何处理数据本身是无关紧要的。我现在更感兴趣的是如何创建将角色和用户角色类隐藏为不必要信息的通用解决方案。因为我知道它们只是存储X数组的方法,所以我想在后台自动生成它们。@user225453为什么要避免创建表?表正是数据库的用途。推荐的解决方案更灵活、更稳定、更可靠——它只是一个良好的数据库设计(当然,可能有少数情况下它是有保证的,但这些情况很少)。但是,为了完整性,我提供了一个替代解决方案。我不想避免创建表。完全相反。我只是想简化一下,以避免每次需要数据数组时都进行复制粘贴。当然,还可以通过隐藏表来增加代码可读性,这些表的唯一目的是在其他表中表示值数组。字符串解析可以做到这一点,但正如您所说,这是一个可怕的限制性解决方案。@user225453我明白了。嗯,LINQtoSQL在简洁性方面并不是最好的。好了,你被这个样板代码卡住了。如果您正在设计一个供其他人使用的DAL,并且希望保持API的整洁,那么您可以将类型设置为
internal
,并提供包装器属性/扩展方法来访问所需的信息类型。实体框架使您能够直接指定多对多关系,而无需显式指定连接表,并且EF 5支持枚举,如果您需要表示一组固定的值,这会更好。实体框架似乎与我的问题1非常匹配。现在我已经对这两个方面做了一些研究,这似乎也是比LINQtoSQL更可取的解决方案。你是想相应地改变你的答案,让我“喜欢”它,还是我应该自己回答?
var userRoleIds = myUser.UserRoles.Select(ur => ur.roleId);
[Table]
public class UserAccount
{
...
[Column]
private string rawRoles;
public IEnumerable<int> Roles
{
get
{
return (this.rawRoles == null)
? return new int[0] :
: this.rawRoles.Split(",").Select(s => int.Parse(s));
}
set
{
this.rawRoles = (value == null)
? null
: String.Join(",", value);
}
}
}