0

MySqlの上にNHibernateを備えたCastleActiveRecordを使用して、比較的単純なユーザー管理モデルを実装していますが、問題が発生しました。 次のSQLcreateステートメントで記述された 2つのテーブル_ユーザーと_パスワードがあるとします。

CREATE TABLE _users(
  id bigint(20)NOT NULL AUTO_INCREMENT、
  ユーザー名char(32)NOT NULL、
  主キー(id)、
  UNIQUE KEY username_UQ(username)、
)ENGINE = InnoDB DEFAULT CHARSET = utf8;

CREATE TABLE _passwords(
  id bigint(20)NOT NULL AUTO_INCREMENT、
  Creation_date datetime NOT NULL、
  user_id bigint(20)NOT NULL、
  password_hash char(64)NOT NULL、
  valid_end_date datetime NOT NULL、
  主キー(id)、
  一意のキーuser_id_password_UQ(user_id、password_hash)、
  KEY user_passwords_FK(user_id)、
  CONSTRAINT user_passwords_FK FOREIGN KEY(user_id)REFERENCES _users( `id`)ON DELETE NO ACTION ON UPDATE NO ACTION
)ENGINE = InnoDB DEFAULT CHARSET = utf8;

アイデアは、基本的なパスワード履歴を保持することです。したがって、パスワードは別のテーブル_ passwordsに保持されます。これは、 _usersテーブルと多対1の関係にあります。

現在、次のC#コードは、CastleActiveRecordsを使用してこの構造をモデル化しています

namespace DataEntities
{
    [ActiveRecord("_users")]
    public class User : ActiveRecordBase<User>
    {
        [PrimaryKey(PrimaryKeyType.Identity, "id", Access = PropertyAccess.NosetterLowercase)]
        public ulong Id
        {
            get;
            set;
        } // Id

        [Property("username", ColumnType = "String", NotNull = true, Unique = true)]
        [ValidateIsUnique]
        public string Username
        {
            get;
            set;
        } // Username

        [HasMany(typeof(Password))]
        public IList<Password> Passwords
        {
            get;
            set;
        } // Passwords

        public string ValidPasswordHash
        {
            get
            {
                DateTime l_dtNow = DateTime.Now;
                if (Passwords.Count != 1 || Passwords[0].ValidFrom >= l_dtNow || Passwords[0].ValidUntil <= l_dtNow)
                {
                    throw new Exception();
                }

                return Encoding.UTF8.GetString(Passwords[0].PasswordHash);
            }
        } // ValidPasswordHash

        public static User FindByCredentials(string i_sUsername, string i_sHashedPassword)
        {
            return FindOne(Restrictions.Eq("Username", i_sUsername), Restrictions.Eq("ValidPasswordHash", i_sHashedPassword));
        } // FindByCredentials
    } // User

    [ActiveRecord("_passwords")]
    public class Password : ActiveRecordBase<Password>
    {
        [PrimaryKey(PrimaryKeyType.Identity, "id", Access = PropertyAccess.NosetterLowercase)]
        public ulong Id
        {
            get;
            set;
        } // Id

        [BelongsTo("user_id", NotNull = true, UniqueKey = "_passwords_UQ1")]
        public ulong UserId
        {
            get;
            set;
        } // UserId

        [Property("password_hash", ColumnType = "UInt64", NotNull = true, UniqueKey = "_passwords_UQ1")]
        public byte[] PasswordHash
        {
            get;
            set;
        } // PasswordHash

        [Property("creation_date", ColumnType = "DateTime", NotNull = true)]
        public DateTime ValidFrom
        {
            get;
            set;
        } // ValidFrom

        [Property("valid_end_date", ColumnType = "DateTime", NotNull = true)]
        public DateTime ValidUntil
        {
            get;
            set;
        } // ValidUntil
    } // Password
} // DataEntities

そして私のアプリケーションの開始時にフレームワークが初期化されます

try
{
    ActiveRecordStarter.Initialize(ActiveRecordSectionHandler.Instance, typeof(Password),
                                                                        typeof(User));
}
catch (Exception l_excpt)
{
    // handle exception
}

最後に、このコードを実行すると、次の例外が生成されます。

Castle.ActiveRecord.Framework.ActiveRecordException:ActiveRecordは、関係User.Passwordsに関する詳細を推測しようとしましたが、ターゲットタイプDataEntities.Passwordに「BelongsTo」マップされたプロパティが見つかりませんでした。
   Castle.ActiveRecord.Framework.Internal.SemanticVerifierVisitor.VisitHasMany(HasManyModel model)のc:\ daten \ dev \ External \ Castle \ AR2.0 \ ActiveRecord \ Castle.ActiveRecord \ Framework \ Internal \ Visitors \ SemanticVerifierVisitor.cs:line 544
   Castle.ActiveRecord.Framework.Internal.AbstractDepthFirstVisitor.VisitNodes(IEnumerableノード)のc:\ daten \ dev \ External \ Castle \ AR2.0 \ ActiveRecord \ Castle.ActiveRecord \ Framework \ Internal \ Visitors \ AbstractDepthFirstVisitor.cs:line 45
   Castle.ActiveRecord.Framework.Internal.AbstractDepthFirstVisitor.VisitModel(ActiveRecordModel model)in c:\ daten \ dev \ External \ Castle \ AR2.0 \ ActiveRecord \ Castle.ActiveRecord \ Framework \ Internal \ Visitors \ AbstractDepthFirstVisitor.cs:line 59
   Castle.ActiveRecord.Framework.Internal.SemanticVerifierVisitor.VisitModel(ActiveRecordModel model)in c:\ daten \ dev \ External \ Castle \ AR2.0 \ ActiveRecord \ Castle.ActiveRecord \ Framework \ Internal \ Visitors \ SemanticVerifierVisitor.cs:line 122
   Castle.ActiveRecord.Framework.Internal.AbstractDepthFirstVisitor.VisitNodes(IEnumerableノード)のc:\ daten \ dev \ External \ Castle \ AR2.0 \ ActiveRecord \ Castle.ActiveRecord \ Framework \ Internal \ Visitors \ AbstractDepthFirstVisitor.cs:line 45
   Castle.ActiveRecord.ActiveRecordStarter.RegisterTypes(ISessionFactoryHolderホルダー、IConfigurationSourceソース、IEnumerable`1タイプ、ブール値ignoreProblematicTypes)のc:\ daten \ dev \ External \ Castle \ AR2.0 \ ActiveRecord \ Castle.ActiveRecord \ Framework \ ActiveRecordStarter.cs :行927
   Castle.ActiveRecord.ActiveRecordStarter.Initialize(IConfigurationSource source、Type [] types)in c:\ daten \ dev \ External \ Castle \ AR2.0 \ ActiveRecord \ Castle.ActiveRecord \ Framework \ ActiveRecordStarter.cs:line 202
   C:\ Projects Code \ xyz \ Global.asax.cs:line 22のGlobal.Application_Start(Object sender、EventArgs e)で

UserIdさて、私はクラスの所有物を際限なく見つめ、グーグルで検索しましたPasswordが、今ではかなり迷っています。ですから、コミュニティは私の最後の希望です...この例外の原因とその修正方法を理解するのを誰かが助けてくれますか?

返信やコメントをよろしくお願いします。

4

1 に答える 1

1

User User { get; set; }外部キーの代わりに参照プロパティが必要です。

公式ドキュメントから始めるのが良いでしょう。

于 2012-11-19T02:24:29.670 に答える