Reputation: 2719
I'm trying to access a property of an entity I've retrieved from NHibernate. I'm getting the following error:
PropertyAccessException:
Invalid Cast (check your mapping for property type mismatches);
setter of Nep.Domain.Model.Doc.
Here's the code. The problem happens when I'm trying to assign the str variable.
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
}
}
What's REALLY strange is if I put a breakpoint on the that line, when I first hover over the dMessage.Doc.Doc.Title, the IDE shows the exception. But, if I move the mouse and hover a second time, then the value of the property comes back correctly!!!! And if I remove the breakpoint all together it always fires the exception. Obviously there's a timing problem here: is there something that I'm required to do before accessing the variable?
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;
}
}
And my IDoc interface:
public interface IDoc
{
int Id { get; set; }
string Title { get; set; }
long Size { get; set; }
string FileName { get; set; }
DateTime CreatedOn { get; set; }
}
And the SQLServer Doc table:
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
Upvotes: 2
Views: 2533
Reputation: 2719
Well, I figured this out after a lot of trial and error. Even though it was complaining when I tried accessing the Title property, it was the Size property that was the culprit. When I changed it from Int32 to Int64 everything worked. I'm a little confused by this since the SqlServer field is int. I would have thought that Int32 would have covered that but I guess not. That's another question for another day.
Upvotes: 2