3

次に、Fluent NHibernateとその自動マッピング機能を使用して、次の簡略化されたPOCOクラスをマッピングしています。

public class Webpage
{    
public virtual int Id { get; set; }    
public virtual string UrlIdentifier { get; set; }    
public virtual WebpageType WebpageType { get; set; }    
}

public class WebpageType
{    
public virtual int Id { get; set; }    
public virtual string Name { get; set; }       
}

次に、次のマッピングをオーバーライドして、WebページからWebpageTypeへのカスケードを明示的に設定しません。

public class WebpageMap : IAutoMappingOverride<Webpage>
{
    public void Override(AutoMapping<Webpage> mapping)
    {
        mapping.References(w => w.WebpageType).Cascade.None();    
    }
}

純粋なNHibernateリーダーの場合、fluentによって生成されるxmlマッピングは次のとおりです。

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
  <class xmlns="urn:nhibernate-mapping-2.2" name="EveryPage.Core.Domain.Webpage, EveryPage.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Webpage`">
    <id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0">
      <column name="Id" />
      <generator class="identity" />
    </id>
    <property name="UrlIdentifier" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="UrlIdentifier" />
    </property>
    <many-to-one cascade="none" class="EveryPage.Core.Domain.WebpageType, EveryPage.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="WebpageType">
      <column name="WebpageType_id" />
    </many-to-one>    
  </class>
</hibernate-mapping>


<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
  <class xmlns="urn:nhibernate-mapping-2.2" name="EveryPage.Core.Domain.WebpageType, EveryPage.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`WebpageType`">
    <id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0">
      <column name="Id" />
      <generator class="identity" />
    </id>
    <property name="Name" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Name" />
    </property>
  </class>
</hibernate-mapping>

問題は、更新がWebページを介してWebpageTypeにカスケードされないことをテストするときに発生します。基本的には、カスケードされます。

私は次のテストを行っています:

    [Test]
    public void Assert_SaveOrUpdate_On_Webpage_Does_Not_Cascade_Update_To_WebpageType()
    {
        // Get the existing webpage.
        webpage = _webpageRepository.Get("~/testwebpage1.aspx");

        // Update the WebpageType.
        const string webpageTypeName = "qwerty test";
        webpage.WebpageType.Name = webpageTypeName;

        // Save the changes.
        Assert.DoesNotThrow(() => _webpageRepository.SaveOrUpdate(webpage));

        // We need to flush the changes to the store for it to execute the changes.
        Assert.DoesNotThrow(() => NHibernateSession.Current.Flush());

        // Remove the webpage and tag from the level 1 cache so we force a trip to the store on our next check.
        NHibernateSession.Current.Evict(webpage);

        //  Check that the webpageType has not been updated.
        webpageType = _webpageTypeRepository.Get(webpageType.Id);
        Assert.AreNotEqual(webpageTypeName, webpageType.Name);
    }

上記のテストはグローバルトランザクションにラップされています。

テストは失敗し、NHibernateは関連するWebpageTypeの名前の更新を実行します。削除および保存(新規作成)カスケードは正しく機能し、カスケードされません。

カスケードを誤解したか、ロジック/テストに問題がありますか?

任意のヘルプ/アドバイスをいただければ幸いです。ありがとう。

4

3 に答える 3

4

アプリが WebPageType のプロパティを誤って変更するのを止めようとしている場合は、マッピングで WebPageType を ReadOnly としてマークすることで、これを実現する方が簡単で安全だと思います。そうすれば、すべての関連付けでカスケードを処理して保護する必要がなくなります。

于 2010-01-11T20:58:46.110 に答える
3

これは、カスケードの意味を誤解していると思います。

あなたの例では、カスケードを何に設定しても、NHibernate は WebPageType の Name プロパティを更新します。考えてみると、NHibernate ライブラリは、WebPage インスタンスからの関連付けを使用してプロパティの値を操作しているのか、それとも「直接」行われたのかをどのように判断しますか?

NHibernate でのカスケードの設定は、各エンティティ内の実際の値がどのように処理されるかではなく、エンティティ間の関連付けがどのように処理されるかを示します。たとえば、カスケード削除を設定できます。これにより、エンティティ自体が削除されると、関連付けられたエンティティが自動的に削除されます。

物事のブログ投稿は物事を少し明確にするか、少なくともある種の参照として機能するかもしれません: http://ayende.com/Blog/archive/2006/12/02/NHibernateCascadesTheDifferentBetweenAllAlldeleteorphansAndSaveupdate.aspx

于 2010-01-11T21:14:00.163 に答える
0

あなたのリポジトリは何をしますか?Webページタイプでsaverupdateが実行されないことを確認してください。そうでない場合は、この動作の明確な説明は表示されません。

于 2010-01-09T17:33:03.040 に答える