2

我需要用未知大小的字符串、整数或其他数组创建 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 类中的简单“List<> 角色”。

我宁愿做这样的事情:

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>”。在数据库类(“B”)中,我做了一些静态方法来授予对正确数据库的访问权限。然后在 MySQLList 中,我通过重载 List<> -方法来操作数据库。这应该会导致“在后台”构建和访问表 UserAccount_roles,因为程序员(主要是我)在自定义 List<> 上看到的只是简化的解决方案。

我的实际问题是:

  1. 我敢打赌,有一些现成的实现。我在哪里可以找到一个?
  2. 我认为我无法在 MySQLList<> 中执行任何“[table] class MyTable”-declarations。我是否必须在那里进行实际的 SQL 语言编码,或者有什么方法可以在编译/运行时创建 Linq to SQL 类和属性的东西?
  3. 这种方法有什么一般性的警告吗?-)
4

1 回答 1

1

如果您想避免显式声明联结表,实体框架可能更适合您。它将允许您直接创建多对多关系,而无需中间类型。

延伸阅读


推荐的方法是在 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 查询中使用它,而且它的数据库设计非常糟糕 - 但是,至少它满足您的要求。

于 2013-04-07T13:42:41.763 回答