0

次のユーザーエンティティがあります。

public class User
{
    public virtual int Id { get; set; }

    public virtual string Username { get; set; }

    public virtual string UsernameLowercase { get { return Username.ToLowerInvariant(); } }

    public virtual string Password { get; set; }

    public virtual string Email { get; set; }

    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
            return false;

        if (ReferenceEquals(this, obj))
            return true;

        var otherUser = obj as User;
        return (0 == string.CompareOrdinal(UsernameLowercase, otherUser.UsernameLowercase));
    }

    public override int GetHashCode()
    {
        return UsernameLowercase.GetHashCode();
    }
}

および次の役割エンティティ:

public class Role
{
    public virtual int Id { get; set; }

    public virtual string RoleName { get; set; }

    public virtual string RoleNameLowercase { get { return RoleName.ToLowerInvariant(); } }

    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
            return false;

        if (ReferenceEquals(this, obj))
            return true;

        var otherRole = obj as Role;
        return (0 == string.CompareOrdinal(RoleNameLowercase, otherRole.RoleNameLowercase));
    }

    public override int GetHashCode()
    {
        return RoleNameLowercase.GetHashCode();
    } 
}

ユーザーには多くの役割を割り当てることができるため、UserInRoleという3番目のエンティティを作成しました。

public class UserInRole
{
    public virtual User User { get; set; }

    public virtual Role Role { get; set; }

    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
            return false;

        if (ReferenceEquals(this, obj))
            return true;

        var other = obj as UserInRole;
        return (Role == other.Role && User == other.User);
    }

    public override int GetHashCode()
    {
        return User.GetHashCode() ^ Role.GetHashCode();
    }
}

流暢なnhibernateを使用してUsersInRolesテーブルとUserテーブルおよびRoleテーブルをマッピングして、ユーザーを削除すると、UsersInRolesテーブルで定義されているすべてのユーザーのロールが自動的に削除されるようにします。UserInRoleエンティティの現在のマッピングクラスは次のとおりです。

public class UserInRoleMapping : ClassMap<UserInRole>
{
    public UserInRoleMapping()
    {
        Table("UsersInRoles");

        CompositeId().
            KeyReference(x => x.User,k => k.Not.Lazy(), "UserId").
            KeyReference(x => x.Role, k => k.Not.Lazy(), "RoleId");

    }
}

あなたの助けに感謝します。

4

1 に答える 1

1

それで、いつか検索した後、私はこの議論を見つけます。Userエンティティを次のように変更します(新しい保護されたRolesプロパティに注意してください)。

public class User
{
    private IList<UserInRole> _roles = new List<UserInRole>(); 

    public virtual int Id { get; set; }

    public virtual string Username { get; set; }

    public virtual string UsernameLowercase { get { return Username.ToLowerInvariant(); } }

    public virtual string Password { get; set; }

    public virtual string Email { get; set; }

    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
            return false;

        if (ReferenceEquals(this, obj))
            return true;

        var otherUser = obj as User;
        return (0 == string.CompareOrdinal(UsernameLowercase, otherUser.UsernameLowercase));
    }

    public override int GetHashCode()
    {
        return UsernameLowercase.GetHashCode();
    }

    protected virtual IList<UserInRole> Roles
    {
        get { return _roles; }
        set
        {
            value.ThrowIfNull("value");
            _roles = value;
        }
    } 
}

ユーザーマッピングは、次のようにHasMany定義を含むように変更されました。

public abstract class UserMapping: ClassMap<User>
{
    protected UserMapping()
    {
        Table("Users");

        Map(x => x.Username).Column("Username").Length(20).Not.Nullable().Unique();
        Map(x => x.Password).Column("Password").Length(20).Not.Nullable();
        Map(x => x.Email).Column("Email").Length(50).Not.Nullable();

        //This line was missing
        HasMany<UserInRole>(Reveal.Member<User>("Roles")).
            Table("UsersInRoles").
            KeyColumn("UserId").
            Inverse().
            Cascade.Delete();
    }
}

これで、ユーザーを削除すると、ロールもエラーなしで削除されます。nhibernateログを見ると、次のように1回のDelete(user)呼び出しに対して2つのdeleteステートメントが表示されます。

13:18:39.950 [7] DEBUG NHibernate.SQL - DELETE FROM UsersInRoles WHERE UserId = :p0 AND RoleId = :p1;:p0 = 7 [Type: Int32 (0)], :p1 = 3 [Type: Int32 (0)]
13:18:39.983 [7] DEBUG NHibernate.SQL - DELETE FROM Users WHERE Id = :p0;:p0 = 7 [Type: Int32 (0)]

これが誰かに役立つことを願っています。ご意見をお待ちしております。

于 2012-10-23T11:49:33.120 に答える