NHibernate PropertyAccessException:访问变量时无效的转换

时间:2011-11-07 07:15:27

标签: nhibernate exception

我正在尝试访问我从NHibernate检索到的实体的属性。我收到以下错误:

PropertyAccessException:
    Invalid Cast (check your mapping for property type mismatches);  
    setter of Nep.Domain.Model.Doc.

这是代码。当我尝试分配str变量时会发生问题。

public PendingApprovalsModel(IEnumerable<IPackage> DomainPackages)
{
    string str = "";
    foreach (Package dPackage in DomainPackages.Where(p => p.HasUnApprovedComponents))
        foreach( Component dComponent in dPackage.Components.Where(c => c.ClientApprovalIsNeeded) )
            foreach (Message dMessage in dComponent.Messages.OrderByDescending(m => m.CreatedOn))
                foreach (MessageDoc dMessageDoc in dMessage.Docs)
                {
                    str = dMessageDoc.Doc.Title;  //<<==ERROR HAPPENS HERE
                }
}

真正奇怪的是,如果我在该行上放置一个断点,当我第一次将鼠标悬停在dMessage.Doc.Doc.Title上时,IDE会显示异常。但是,如果我移动鼠标并再次悬停,那么该属性的值会正确返回!如果我一起删除断点,它总是触发异常。显然这里有一个时间问题:在访问变量之前我是否需要做些什么?

Doc.hbm.xml:

<class name="Doc" table="Doc" dynamic-update="true">
    <id name="Id" column="Id" type="Int32" unsaved-value="0">
        <generator class="identity" />
    </id>

    <version name="RowVersion" column="RowVersion" />
    <property name="Title" length="100" type="AnsiString" not-null="true" />
    <property name="Size" type="Int32" not-null="true" />
    <property name="FileName" length="200" type="AnsiString" not-null="true" />
    <property name="CreatedOn" type="DateTime" not-null="true" />

    <bag name="Messages" cascade="all">
        <key column="DocId" />
        <one-to-many class="MessageDoc"/>
    </bag>

</class>

Message.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                                     assembly="Nep.Domain"
                                     namespace="Nep.Domain.Model" schema="Nep_db.dbo" default-lazy="true">

    <class name="Message" table="Message" where="IsDeleted = 0" dynamic-update="true"  >
        <id name="Id" column="Id" type="Int32" unsaved-value="0">
            <generator class="identity" />
        </id>

        <version name="RowVersion" column="RowVersion" />

        <property name="Text" type="AnsiString" length="2000" not-null="true" />
        <property name="HasBeenRead" type="bool" not-null="true" />
        <property name="HasBeenEmailed" type="bool" not-null="true" />
        <property name="IsDeleted" type="bool" not-null="true" />
        <property name="CreatedOn" type="DateTime" not-null="true" />
        <property name="LastChangedOn" type="DateTime" not-null="true" />
        <property name="DeletedOn" type="DateTime" not-null="false" />

        <many-to-one name="CreatedBy" class="UserBase" column="CreatedByUserId" />
        <many-to-one name="Component" class="Component" column="ComponentId" />

        <bag name="Docs" cascade="all">
            <key column="MessageId" />
            <one-to-many class="MessageDoc"/>
        </bag>
    </class>
</hibernate-mapping>

Doc class:

public class Doc : IDoc
{
    private HttpPostedFileBase _file;
    public virtual int Id { get; set; }
    public virtual string Title { get; set; }
    public virtual long Size { get; set; }
    public virtual string FileName { get; set; }
    public virtual DateTime CreatedOn { get; set; }
    public virtual IList<MessageDoc> Messages { get; private set; }
    protected virtual int RowVersion { get; set; }
    public virtual HttpPostedFileBase HttpFile
    {
        get
        {
            return _file;
        }
        set {
            _file = value;
            Title = value.FileName;
            FileName = value.FileName;
            Size = value.ContentLength;
        } 
    }
    public Doc()
    {
        Messages = new List<MessageDoc>();
    }

    public Doc(HttpPostedFileBase attachment)
        : this()
    {
        HttpFile = attachment;
    }
}

我的IDoc界面:

public interface IDoc
{
    int Id { get; set; }
    string Title { get; set; }
    long Size { get; set; }
    string FileName { get; set; }
    DateTime CreatedOn { get; set; }
}

和SQLServer Doc表:

 CREATE TABLE [dbo].[Doc](
        [Id] [int] IDENTITY(1,1) NOT NULL,
        [Title] [varchar](100) NOT NULL,
        [Size] [int] NOT NULL,
        [FileName] [varchar](200) NOT NULL,
        [CreatedOn] [datetime2](7) NOT NULL,
        [RowVersion] [int] NOT NULL,
     CONSTRAINT [PK_Doc] PRIMARY KEY CLUSTERED 
    (
        [Id] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]

    GO

    ALTER TABLE [dbo].[Doc] ADD  CONSTRAINT [DF_Doc_Title]  DEFAULT ('') FOR [Title]
    GO

    ALTER TABLE [dbo].[Doc] ADD  CONSTRAINT [DF_Doc_Size]  DEFAULT ((0)) FOR [Size]
    GO

    ALTER TABLE [dbo].[Doc] ADD  CONSTRAINT [DF_Doc_FileName]  DEFAULT ('') FOR [FileName]
    GO

    ALTER TABLE [dbo].[Doc] ADD  CONSTRAINT [DF_Doc_CreatedOn]  DEFAULT (getdate()) FOR [CreatedOn]
    GO

1 个答案:

答案 0 :(得分:2)

好吧,经过大量的试验和错误,我想到了这一点。即使我在尝试访问Title属性时抱怨,但是Size属性是罪魁祸首。当我将它从Int32更改为Int64时,一切正常。我对此有点困惑,因为SqlServer字段是int。我本以为Int32会覆盖那个,但我猜不是。那是另一天的另一个问题。