当记录是GUID时出现无效转换错误

3

这个基础架构的类型是多对多关系,ID 的类型是 GUID…同时避免出现这个错误:

{"Unable to cast object type \"NHibernate.Collection.Generic.PersistentGenericSet`1[Hospital1.Domain.BPatient]\" the type \"System.Collections.Generic.ISet`1[Hospital1.Domain.BPatient]\"."}

Message: 
Invalid Cast (check your mapping for property type mismatches); setter of Hospital1.Domain.BDoctor

BDoctor.cs

 namespace Hospital1.Domain {
 public class BDoctor
 {
     public virtual Guid id { get; set; }
     public virtual string doctor { get; set; }
     public virtual ISet<BPatient> BPatients { get; set; }


     public BDoctor()
     {
         BPatients = new HashSet<BPatient>();
     }

 } }

BPatient.cs

 namespace Hospital1.Domain {
 public class BPatient
 {
     public virtual Guid id { get; set; }
     public virtual string name { get; set; }
     public virtual int growth { get; set; }
     public virtual int weight { get; set; }
     public virtual ISet<BDoctor> BDoctors { get; set; }


 } }

BDoctor.hbm.xml

 <?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping
                xmlns="urn:nhibernate-mapping-2.2"
                assembly="Hospital1"
                namespace="Hospital1.Domain">   <class name="BDoctor" table="BDoctor">

  <id name="id" column="id">
   <generator class="guid.comb" />
 </id>


 <property name="doctor" column="doctor"/>
 <set name="BPatients" table="BNote">

   <key column="iddoc" />
   <many-to-many class="BPatient" column="id" />

 </set>   </class> </hibernate-mapping>

BPatient.hbm.xml

 <?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping
                xmlns="urn:nhibernate-mapping-2.2"
                assembly="Hospital1"
                namespace="Hospital1.Domain">   <class name="BPatient" table="BPatient">


 <id name="id" column="id"><generator class="guid.comb" />
 </id>


 <property name="name" column="name"/>
 <property name="growth" column="growth"/>
 <property name="weight" column="weight"/>



 <set name="BDoctors" table="BNote" inverse="true">
   <key column="idpat" />
   <many-to-many class="BDoctor" column="id" />

 </set>   </class> </hibernate-mapping>

XAML.CS

         myConfiguration = new Configuration();
         myConfiguration.Configure();
         mySessionFactory = myConfiguration.BuildSessionFactory();
         mySession = mySessionFactory.OpenSession();


         BPatient patient = new BPatient();
         patient.name = "Roman";
         patient.growth = Convert.ToInt32("183");
         patient.weight = Convert.ToInt32("90");
         mySession.Save(patient);

         BDoctor doctori = new BDoctor();
         doctori.doctor = "Andry";
         doctori.BPatients.Add(patient);
         mySession.Save(doctori);
     }

App.config

 <?xml version="1.0" encoding="utf-8" ?> <configuration>  
 <configSections>
     <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />  
 </configSections>

   <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
     <session-factory>
       <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
       <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
       <property name="query.substitutions">hqlFunction=SQLFUNC</property>
       <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
       <property name="connection.connection_string">Data Source=(local);Initial Catalog=Hospital;Integrated
 Security=True</property>
       <property name="show_sql">true</property>
       <mapping assembly="Hospital1" />
     </session-factory>   </hibernate-configuration>
      <startup> 
         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
     </startup> </configuration>

你使用的 ISet 版本是哪个?NHibernate.Collection.Generic.PersistentGenericSet<T> 继承自 Iesi.Collections.Generic.ISet<T> 而不是 System.Collections.Generic.ISet<T>,这可能会导致你的问题。 - Réda Mattar
我是初学者,不知道如何检查Iset的版本,现在我已经将它替换为Ilist,但无论如何都出现了相同的错误。 =) - user2908367
但我使用NUGET的Fluent Nhibernate。 - user2908367
1个回答

2
这里的类型转换问题是由于存在两个ISet,你引用了“错误”的一个。
我的意思是,在你的代码中,你会有(好吧,我会这么说):
using System.Collections.Generic; // where ISet is
...
public class BDoctor
{
     public virtual ISet<BPatient> BPatients { get; set; } // System... ISet

NHibernate使用Iesi.Collections.1.0.1集合。

using Iesi.Collections.Generic;  // ISet<>

您可以通过NuGet获取此软件包:
<package targetFramework="net40" version="1.0.1.0"    id="Iesi.Collections" />

编辑:我们解决了 Iesi 之后... 接下来让我们修复下一个问题

所以,你可以使用 <set> 和 Iesi 的 ISet<>,或者你可以更改映射为 <bag> 并使用本地的 c# IList<>。但在你的集合映射中,你必须设置正确的列名,对于 多对多 关系,所以不要这样:

<set name="BDoctors" table="BNote" inverse="true">
   <key column="idpat" />
   <many-to-many class="BDoctor" column="id" />
</set> 
..
<set name="BPatients" table="BNote">
   <key column="iddoc" />
   <many-to-many class="BPatient" column="id" />
</set>

对于 IList<> 我们可以使用 bag,并查看列映射中的差异。

<bag name="BDoctors" table="BNote" inverse="true">
   <key column="idpat" />
   <many-to-many class="BDoctor" column="iddoc" />
</bag> 
..
<bag name="BPatients" table="BNote">
   <key column="iddoc" />
   <many-to-many class="BPatient" column="idpat" />
</bag>

如果BNote表中有ID列,更好的方法是使用<idbag>。具体请参考此链接

PM> 安装程序包 Iesi.Collections -Version 1.0.1 成功安装 'Iesi.Collections 1.0.1'。 安装失败。正在回滚... Install-Package : 已引用较新版本的 'Iesi.Collections'。 行:1 字符:1
  • Install-Package Iesi.Collections -Version 1.0.1
  • + CategoryInfo : NotSpecified: (:) [Install-Package], InvalidOperationException + FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PowerShell.Commands.InstallPackageCommand
- user2908367
好的,我明白了...也许你已经有了最新版本(比1.0.1更新)。我正在使用带有IESI的NHibernate 3.3,它可以正常工作。可能你的更新版本也可以。无论如何,请在你的实体/POCO项目中引用IESI。将System中的ISet更改为Iesi...一切都会正常工作(IESI的版本根本不是问题)。问题是要使用正确的ISet。请在更改到Iesi后告诉我是否正常工作(我相信它会的 ;) - Radim Köhler
好的,使用 IList<> 吧。主要的区别是,使用 Iesi 的 ISet<> 会为您做更多的工作,例如不允许添加更多相同(Equal())的项目,而对于 List 没有这样的限制。但我们只使用 IList<bag>,而且它运行良好。所以,现在我们已经解决了异常问题...您能否跟踪由 NHibernate 生成的 SQL,并检查在手动执行时是否选择了相关患者和医生? - Radim Köhler
我发现你的映射存在一些问题,请扩展回答。 - Radim Köhler
在任何情况下,如果列表中的数据没有填充,我会在跟踪中提供一个链接,也许你能从这里看到什么? - user2908367
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接