使用Linq to SQL简化创建数组列

时间:2013-04-07 08:51:22

标签: c# sql arrays linq linq-to-sql

我需要创建具有未知大小的字符串,整数或其他任何数组的SQL表。最好的方法是为它创建单独的表。像这样(伪代码如下,我不知道我是否正确使用“主键”):

public class DataBase : DataContext
{
    public Table<UserAccount> users { get { return GetTable<UserAccount>(); } }
    public Table<UserAccount_roles> userroles { get { return GetTable<UserAccount_roles>(); } }
}

[Table]
public class UserAccount
{
    [Column(IsPrimaryKey = true)]
    public string username;
    [Column]
    public string password;
}

[Table]
public class UserAccount_roles
{
    [Column(IsPrimaryKey = true)]
    public string userName;
    [Column(IsPrimaryKey = true, IsDbGenerated = true)]
    public int roleIdx;
    [Column]
    public int arrayValue;
}

但是,如果我不应该担心SQL实现,UserAccount_roles可能只是UserAccount-class中的简单“List&lt;&gt;角色”,这感觉很笨拙。

我宁愿做这样的事情:

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;
}

我想过做“class MySQLList<B, T> : List<T>”。在DataBase-class(“B”)中,我创建了一些静态方法来授予对正确数据库的访问权限。然后在MySQLList中我通过重载List&lt;&gt;操纵数据库-方法。这应该导致构建和访问表UserAccount_roles“在幕后”,因为程序员(主要是我)在自定义List&lt;&gt;上看到表单中的简化解决方案。

我的实际问题是:

  1. 我打赌有一些现成的实现。哪里可以 找一个?
  2. 我想我无法做任何“[table] class MyTable” - MySQLList&lt;&gt;中的声明。我是否必须在那里进行实际的SQL语言编码,或者是否有任何方法可以创建Linq to SQL -class和 编译/运行时属性?
  3. 这种方法的任何一般性警告? - )

1 个答案:

答案 0 :(得分:1)

如果您想避免必须明确声明联结表,Entity Framework可能更适合您。它允许您直接创建多对多关系,而无需中间类型。

进一步阅读


建议的方法是在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); }
    }
}

这比更好于拥有必须在C#中解析和处理的序列化整数数组。您可以轻松地执行以下操作:

var userRoleIds = myUser.UserRoles.Select(ur => ur.roleId);

但是你也可以使用序列化阵列做更多的事情。

进一步阅读


如果你真的想将数组存储在一个列中,我担心在Linq-to-SQL中没有标准的方法(可能某些第三方提供商会支持它)。您最好的选择是自己进行序列化,如下所示:

[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);
        }
    }
}

当然,有更好的方法来序列化您的数据,这只是一个例子。你不能在任何Linq-to-SQL查询中使用它,而且它的数据库设计非常糟糕 - 但是,至少它满足你的要求。