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-class 内の単純な「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<> メソッドによってデータベースを操作します。プログラマー (主に私) は、カスタマイズされた List<> の形式で単純化されたソリューションを表示するだけなので、これにより、テーブル UserAccount_roles の構築とアクセスが「フードの下で」行われるはずです。

私の実際の質問は次のとおりです。

  1. これにはいくつかの準備が整った実装があるに違いありません。どこで見つけられますか?
  2. 「[table] class MyTable」-MySQLList<> での宣言を行うことができないと思います。そこで実際のSQL言語コーディングを行う必要がありますか、またはコンパイル/実行時にLinq to SQLクラスと属性のものを作成する方法はありますか?
  3. このアプローチで一般的な注意事項はありますか?-)
4

1 に答える 1

1

ジャンクション テーブルを明示的に宣言する必要がないようにする場合は、Entity Frameworkの方が適している可能性があります。中間タイプを必要とせずに、多対多の関係を直接作成できます。

参考文献


これを行うための推奨される方法は、Linq-To-SQL で多対多の関係を持つ 2 つのテーブルを作成することです。

[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 に答える