0

ASP.NETページのGridViewにデータを読み込もうとしているときに問題が発生しました。私はNHibernateにまったく慣れていないので、マッピングツールとして使用しようとしています。

私は次のXMLマッピングスキーマを持っています:

状態

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="CMMS.BLL.Status, CMMS" table="tblStatus">
    <id name="StatusID" column="StatusID" unsaved-value="0">
      <generator class="identity" />
    </id>
    <property name="StatusCode" column="StatusCode" />
    <property name="StatusNote" column="StatusNote" />
  </class>
</hibernate-mapping>

作業命令

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class name="CMMS.BLL.WorkOrder, CMMS" table="WorkOrder">
        <id name="ID" column="ID" type="Int32"> 
            <generator class="identity" /> 
        </id>
        <property name="WOID" column="WOID" type="String" length="50" />
        <property name="WOReference" column="WOReference" type="String" length="50" />      

            <set name="WorkOrderStatus" table="tblWorkOrderStatus" inverse="true" cascade="all-delete-orphan">
                <key column="WorkOrderID" />
                <one-to-many class="CMMS.BLL.WorkOrderStatus, CMMS" />
         </set> 
    </class>
</hibernate-mapping>

WorkOrderStatus

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="CMMS.BLL.WorkOrderStatus, CMMS" table="tblWorkOrderStatus">
    <id name="WSID" column="WSID" type="Int32" unsaved-value="0">
      <generator class="identity" />
    </id>

    <property name="Comments" column="Comments" />
    <property name="LastModifiedOn" column="LastModifiedOn"  type="Timestamp" />
    <property name="CreatedBy" column="CreatedBy" />

    <many-to-one name="WorkOrder" class="CMMS.BLL.WorkOrder, CMMS" column="WorkOrderID" />
    <many-to-one name="Status" class="CMMS.BLL.Status, CMMS" column="StatusID" />
  </class>
</hibernate-mapping>

およびそのPOCOクラスは次のように定義されます。

状態

public class Status {
    /* Private parameter of object*/
    private int _statusid;
    private string _statuscode ;
    private string _statusnote ;
    //private ISet<WorkOrderStatus> _workorder_status = new HashedSet<WorkOrderStatus>();

    /* Public methode to access object*/
    public virtual int StatusID{
        get { return this._statusid; }
        set { this._statusid  = value; }
    }        

    public virtual string StatusCode{
        get { return _statuscode ; }
        set { _statuscode  = value; }
    }

    public virtual string StatusNote{
        get { return _statusnote; }
        set { _statusnote = value; }
    }

    /*
    public virtual ISet<WorkOrderStatus> WorkOrderStatus
    {
        get { return (_workorder_status); }
        protected set { _workorder_status = value; }
    }
     */ 

    /* Class Constructor */
    public Status() { }
}

作業命令

public class WorkOrder
{
    private int _ID;
    private string _WOID;
    private string _WOReference;        
              private ISet<WorkOrderStatus> _workorder_status;


    public virtual int ID
    {
        get { return this._ID; }
        set { this._ID = value; }
    }

    public virtual string WOID
    {
        get { return this._WOID; }
        set { this._WOID = value; }
    }

         public virtual string WOReference
    {
        get { return _WOReference; }
        set { _WOReference = value; }
    }

    public virtual ISet<WorkOrderStatus> WorkOrderStatus{
                get { return (_workorder_status); }
                protected set { _workorder_status = value; }
     }

    public WorkOrder(){ 
                this._workorder_status = new HashedSet<WorkOrderStatus>();
        } 
}

WorkOrderStatus

public class WorkOrderStatus 
 {

     private int _wsid;
     private string _comments;        
     private DateTime _lastmodifiedon;
     private WorkOrder _workorder;
     private Status _status;
     private int _createdby;


     public virtual int WSID {
         get { return this._wsid; }
         set { this._wsid = value; }
     }

     public virtual string Comments {
         get { return this._comments; }
         set { this._comments = value; }
     }

     public virtual DateTime LastModifiedOn{ 
         get { return _lastmodifiedon; }
         set { _lastmodifiedon = value; }
     }

     public virtual  WorkOrder WorkOrder {
         get { return _workorder; }
         set { _workorder = value; }
     }
     public virtual Status  Status {
         get { return _status; }
         set { _status = value; }
     }

     public virtual int CreatedBy {
         get { return _createdby; }
         set { _createdby = value; }
     }


     public WorkOrderStatus() { }
 }

しかし、GridViewをObjectDataSourceにバインドして、次のステートメントを実行するメソッドにバインドすると、次のようになります。

string strQuery = "SELECT wo.*, st.*, ws.* FROM WorkOrder wo " +
                       "INNER JOIN ( " +
                       "             SELECT * " +
                       "             FROM tblWorkOrderStatus o1 " +
                       "             WHERE LastModifiedOn=( " +
                       "                                    SELECT TOP 1 LastModifiedOn " +
                       "                                    FROM tblWorkOrderStatus o2 " +
                       "                                    WHERE (o1.WorkOrderID = o2.WorkOrderID) " +
                       "                                    ORDER BY LastModifiedOn DESC) " +
                       ")ws ON wo.ID= ws.WorkOrderID " +
                       "INNER JOIN tblStatus st ON ws.StatusID= st.StatusID ";


   strQuery += "ORDER BY wo.WOID";


IList  wo = session.CreateSQLQuery(strQuery)
      .AddEntity("wo", typeof(WorkOrder))
                 .AddEntity("st", typeof(Status))
          .AddEntity("ws", typeof(WorkOrderStatus))  
                .List();
return wo;

SQL Server Profilerで見られる関数からの呼び出しなしで、テーブルtblWorkOrderStatusへの一連のUPDATEがありました。

RPC:Completed   exec sp_executesql N'UPDATE CMMS.dbo.tblWorkOrderStatus SET Comments = @p0, LastModifiedOn = @p1, CreatedBy = @p2, WorkOrderID = @p3, StatusID = @p4 WHERE WSID = @p5',N'@p0 nvarchar(4000),@p1 datetime,@p2 int,@p3 int,@p4 int,@p5 int',@p0=NULL,@p1='2012-07-19 09:44:45.4600000',@p2=0,@p3=7223,@p4=1,@p5=104147    .Net SqlClient Data Provider        
RPC:Completed   exec sp_executesql N'UPDATE CMMS.dbo.tblWorkOrderStatus SET Comments = @p0, LastModifiedOn = @p1, CreatedBy = @p2, WorkOrderID = @p3, StatusID = @p4 WHERE WSID = @p5',N'@p0 nvarchar(4000),@p1 datetime,@p2 int,@p3 int,@p4 int,@p5 int',@p0=NULL,@p1='2012-07-19 09:44:45.4600000',@p2=0,@p3=7226,@p4=1,@p5=104148    .Net SqlClient Data Provider        
RPC:Completed   exec sp_executesql N'UPDATE CMMS.dbo.tblWorkOrderStatus SET Comments = @p0, LastModifiedOn = @p1, CreatedBy = @p2, WorkOrderID = @p3, StatusID = @p4 WHERE WSID = @p5',N'@p0 nvarchar(4000),@p1 datetime,@p2 int,@p3 int,@p4 int,@p5 int',@p0=NULL,@p1='2012-07-19 09:44:45.4600000',@p2=0,@p3=7234,@p4=1,@p5=104150    .Net SqlClient Data Provider        
RPC:Completed   exec sp_executesql N'UPDATE CMMS.dbo.tblWorkOrderStatus SET Comments = @p0, LastModifiedOn = @p1, CreatedBy = @p2, WorkOrderID = @p3, StatusID = @p4 WHERE WSID = @p5',N'@p0 nvarchar(4000),@p1 datetime,@p2 int,@p3 int,@p4 int,@p5 int',@p0=NULL,@p1='2012-07-19 09:44:45.4600000',@p2=0,@p3=7235,@p4=1,@p5=104151    .Net SqlClient Data Provider    

何が問題なのか正確にはわかりません。マッピングファイルか、データベースに問題がある可能性がありますか?手伝っていただけませんか?このソリューションを管理するにはどうすればよいですか?

4

1 に答える 1

1

この現象の最も一般的な原因は、整数としてマップされた列挙型と、null 不可としてマップされた null 値のようです。null 値がデータベースから返されてインスタンスにマップされると、通常はデフォルト値が取得されます。これは NHibernate による変更と見なされるため、セッションがフラッシュされると、影響を受けるエンティティが保存されます。

マッピングをざっと見てみると、列挙型が見当たらなかったので、WorkOrderStatus テーブルに Null 許容として定義されている列があり、おそらくそうであってはならないのではないかと思われます。更新ごとにその列が0(整数のデフォルト値)に設定されるため、それは「CreatedBy」列だと思います。CreatedBy は実際には null 可能であってはならないと思うので、マッピング/エンティティを更新してそうするのはおそらく理想的ではありません。おそらく、列を null 非許容にし、現在 null である行を修正して、何らかのデフォルト値を持つようにすることをお勧めします。

詳細については、How Test your mappings: the Ghostbusterをご覧ください。

于 2012-07-30T13:16:40.803 に答える