NHibernate的对象ID将返回不正确的值 [英] NHibernate object id is returning incorrect value
问题描述
我使用NHibernate的,这是不是一门功课。
假设我已经取回类型的对象教师
(假设工程学院在XYZ的大学)从数据库中。它与它的类型处
相关5子对象,并应包含的ID 2,4,5,8和9,根据数据库表。
我的第一个问题是,我看到相关的对象总是有 ID
设置为 0
。
教师-ID被正确加载。
我的第二个问题是的,我需要将其加载到一个组合框,并希望其ID为5。选择的对象。
我该如何解决的ID设置为0的问题?我不知道为什么会发生。
如何选择ID的对象== 5?
Faculty.hbm.xml
<?XML版本=1.0编码=UTF-8>?;
<休眠映射
的xmlns =金塔:NHibernate的映射 - 2.2
命名空间=UserManagememntApplication.BO
装配=UserManagememntApplication.BO >
<类名=教师表=b_Faculty>
< id列=IDNAME =IDTYPE =System.Int32>
<生成器类=本地/>
< / ID>
<物业柱=代码NAME =密码/>
<物业柱=名称NAME =名称/>
<物业柱=IsActiveNAME =IsActive/>
<包名称=DepartmentItems表=b_Department>
<键列=FacultyID/>
将;一对许多类=部/>
< /袋>
< /班>
< /休眠映射>
Department.hbm.xml
<?XML版本=1.0编码=UTF-8>?;
<休眠映射
的xmlns =金塔:NHibernate的映射 - 2.2
命名空间=UserManagememntApplication.BO
装配=UserManagememntApplication.BO >
<类名=部门表=b_Department>
< id列=IDNAME =IDTYPE =System.Int32>
<生成器类=本地/>
< / ID>
<物业柱=代码NAME =密码/>
<物业柱=名称NAME =名称/>
<物业柱=IsActiveNAME =IsActive/>
<多到一个名称=教师级=教师一栏=FacultyID独一无二=真/>
<包名称=TeacherItems表=b_Teacher>
<键列=的DepartmentID/>
<一到多级=教师/>
< /袋>
< /班>
< /休眠映射>
b_Faculty
CREATE TABLE [DBO]。[b_Faculty(
[ID] [INT] IDENTITY(1,1)NOT NULL,
[代码] [VARCHAR(50)NOT NULL,
〔名称] [VARCHAR(50)NOT NULL,
[IsActive] [位] NOT NULL,
约束[PK_b_Faculty] PRIMARY KEY CLUSTERED
(
[ID ] ASC
)和(PAD_INDEX = OFF,STATISTICS_NORECOMPUTE = OFF,IGNORE_DUP_KEY = OFF,ALLOW_ROW_LOCKS = ON,ALLOW_PAGE_LOCKS = ON)ON [PRIMARY]
)ON [PRIMARY]
b_Department
CREATE TABLE [DBO ]。[b_Department(
[ID] [INT] IDENTITY(1,1)NOT NULL,
[FacultyID] [INT] NOT NULL,
[代码] [VARCHAR(50 )NOT NULL,
[名] [VARCHAR(50)NOT NULL,
[IsActive] [位] NOT NULL,
约束[PK_b_Department] PRIMARY KEY CLUSTERED
(
〔ID] ASC
)和(PAD_INDEX = OFF,STATISTICS_NORECOMPUTE = OFF,IGNORE_DUP_KEY = OFF,ALLOW_ROW_LOCKS = ON,ALLOW_PAGE_LOCKS = ON)ON [PRIMARY]
)ON [PRIMARY]
修改
Faculty.cs
公共类教员:&BusinessObject的LT;学院>
{
公共虚拟字符串代码{搞定;组; }
公共虚拟字符串名称{;组; }
公共虚拟BOOL IsActive {搞定;组; }
公共虚拟IEnumerable的<&系GT; DepartmentItems {搞定;组; }
}
Department.cs
公共类部门:&BusinessObject的LT;系GT&;
{
公共虚拟字符串代码{搞定;组; }
公共虚拟字符串名称{;组; }
公共虚拟BOOL IsActive {搞定;组; }
公共虚拟学院教授{搞定;组; }
公共虚拟IEnumerable的<教师与GT; TeacherItems {搞定;组; }
}
BusinessObject.cs
公共抽象类和BusinessObject的LT; T> :IBusinessObject其中T:&BusinessObject的LT; T>
{
公众诠释ID {搞定;组; }
公共静态布尔运算符==(&BusinessObject的LT; T>项目1,&BusinessObject的LT; T> ITEM2)
{
布尔相同= FALSE;
如果(object.ReferenceEquals(项目1,空)及!&安培;!object.ReferenceEquals(项目2,NULL))
{
如果(item1.ID == ITEM2 .ID)
{
相同= TRUE;
}
}
,否则
{
如果(object.ReferenceEquals(项目1,空)及和放大器; object.ReferenceEquals(项目2,空) )
{
相同= TRUE;
}
}
返回相同的;
}
公共静态布尔运算符=(BusinessObject的< T>项目1,BusinessObject的< T> ITEM2)!
{
回报率(ITEM1 == ITEM2);
}
公众覆盖布尔等于(obj对象)
{
//如果OBJ为null,他们显然不相等。
如果(OBJ == NULL)
{
返回FALSE;
}
//如果对象是相同的实例,它们必须是相等的。
如果(Object.ReferenceEquals(这一点,OBJ))
{
返回真;
}
//如果对象不是同一类型,它们可以不相等。
如果(this.GetType()= obj.GetType()!)
{
返回false;
}
$ B $(B T)= objCustomer(T)目标文件;
如果(this.ID大于0&放大器;&放大器; objCustomer.ID大于0)
{
如果(this.ID.Equals(objCustomer.ID))
{
返回真;
}
}
返回false;
}
公共覆盖INT的GetHashCode()
{
如果(this.ID< = 0)
{
返回基地。 GetHashCode的();
}
,否则
{
返回ID.GetHashCode();
}
}
}
FacultyRepository.cs
公共类FacultyRepository:库<教职员及GT;
{
}
DepartmentRepository.cs
公共类DepartmentRepository:库<&系GT;
{
}
Repository.cs
公共类资源库< T> :IRepository< T>
{
的Isession _session;
公共库()
{
_session = SessionFactory.GetOpenSession();
}
公共吨得到(对象ID)
{$ B $(B T)= OBJ默认(T);
试
{
如果
{
_session.BeginTransaction()(_session.Transaction.IsActive!);
OBJ =(T)_session.Get< T>(ID);
_session.Transaction.Commit();
_session.Flush();
}
,否则
{
抛出新的异常(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
赶上(异常前)
{
_session.Transaction.Rollback();
_session.Clear();
罚球前;
}
返回OBJ;
}
公开的IEnumerable< T>获取(串字段名,对象fieldValue方法)
{
IEnumerable的< T>名单= NULL;
试
{
如果
{
_session.BeginTransaction()(_session.Transaction.IsActive!);
名单=(IEnumerable的< T>)_ session.CreateCriteria(typeof运算(T))
。新增(新NHibernate.Expression.EqExpression(字段名,fieldValue方法))
的.List< T>( );
_session.Transaction.Commit();
_session.Flush();
}
,否则
{
抛出新的异常(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
赶上(异常前)
{
_session.Transaction.Rollback();
_session.Clear();
罚球前;
}
返回列表;
}
公开的IEnumerable< T>获得()
{
IEnumerable的< T>名单= NULL;
试
{
如果
{
_session.BeginTransaction()(_session.Transaction.IsActive!);
名单=(IEnumerable的< T>)_ session.CreateCriteria(typeof运算(T))名单,LT; T>();
_session.Transaction.Commit();
_session.Flush();
}
,否则
{
抛出新的异常(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
赶上(异常前)
{
_session.Transaction.Rollback();
_session.Clear();
罚球前;
}
返回列表;
}
公共无效SaveOrUpdate(T OBJ)
{
试
{
如果(!_session.Transaction.IsActive)
{
_session.BeginTransaction();
_session.SaveOrUpdateCopy(OBJ);
_session.Transaction.Commit();
_session.Flush();
}
,否则
{
抛出新的异常(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
赶上(异常前)
{
_session.Transaction.Rollback();
_session.Clear();
罚球前;
}
}
公共无效SaveOrUpdate(IEnumerable的< T>的OBJ)
{
试
{
如果(! _session.Transaction.IsActive)
{
_session.BeginTransaction();
的foreach(T OBJ的OBJ文件)
{
_session.SaveOrUpdate(OBJ);
}
_session.Transaction.Commit();
_session.Flush();
}
,否则
{
抛出新的异常(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
赶上(异常前)
{
_session.Transaction.Rollback();
_session.Clear();
罚球前;
}
}
公共无效删除(T OBJ)
{
试
{
如果(!_session.Transaction .IsActive)
{
_session.BeginTransaction();
_session.Delete(OBJ);
_session.Transaction.Commit();
_session.Flush();
}
,否则
{
抛出新的异常(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
赶上(异常前)
{
_session.Transaction.Rollback();
_session.Clear();
罚球前;
}
}
公共无效删除(IEnumerable的< T>的OBJ)
{
试
{
如果(! _session.Transaction.IsActive)
{
_session.BeginTransaction();
的foreach(T OBJ的OBJ文件)
{
_session.Delete(OBJ);
}
_session.Transaction.Commit();
_session.Flush();
}
,否则
{
抛出新的异常(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
赶上(异常前)
{
_session.Transaction.Rollback();
_session.Clear();
罚球前;
}
}
公共无效DeleteAll()
{
试
{
如果(!_session.Transaction.IsActive )
{
_session.BeginTransaction();
的DetachedCriteria标准= DetachedCriteria.For< T>();
&IList的LT; T>清单= criterion.GetExecutableCriteria(_session)的.List< T>();
的foreach(列表中的项目牛逼)
{
_session.Delete(项目);
}
_session.Transaction.Commit();
_session.Flush();
}
,否则
{
抛出新的异常(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
赶上(异常前)
{
_session.Transaction.Rollback();
罚球前;
}
}
公共无效的Dispose()
{
如果(_session!= NULL)
{
_SESSION。明确();
_session.Close();
_session = NULL;
}
}
}
SessionFactory.cs
公共类的SessionFactory
{
私有静态ISessionFactory _sessionFactory = NULL;
私人的SessionFactory(){}
静态的SessionFactory()
{
如果(_sessionFactory == NULL)
{
配置配置=新配置();
configuration.Configure();
_sessionFactory = configuration.BuildSessionFactory();
}
}
公共静态的ISession GetOpenSession()
{
返回_sessionFactory.OpenSession();
}
}
这是我的全部。
这是极其胡乱猜测。你可以尝试没有平等comparers和等于
实施运行的代码,看看是否可以帮助,于是有了下面的实现:
公共抽象类和BusinessObject的LT; T> :IBusinessObject其中T:&BusinessObject的LT; T>
{
公众诠释ID {搞定;组; }
}
您可能会想尝试的另一件事是将 ID
私人
公共抽象类和BusinessObject的LT; T> :IBusinessObject其中T:&BusinessObject的LT; T>
{
公众诠释ID {搞定;私人集; }
}
看什么那是。
$ B $效果bI am using NHibernate and this is not a Homework.
Suppose I have retrieved an object of type Faculty
(suppose Faculty of Engineering in the University of XYZ) from the database. It has 5 child objects associated with it of type Department
and should contain IDs 2,4,5,8 and 9 according to the database-table.
My 1st problem is, I see that the associated objects always have ID
set as 0
.
Faculty-ID is loading correctly.
My 2nd problem is, I need to load them into a combo box and want the object selected whose ID is 5.
How can I solve the problem of ID set to 0? I don't know why it is happening.
How to select the object of ID==5?
Faculty.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping
xmlns="urn:nhibernate-mapping-2.2"
namespace="UserManagememntApplication.BO"
assembly="UserManagememntApplication.BO" >
<class name="Faculty" table="b_Faculty">
<id column="ID" name="ID" type="System.Int32" >
<generator class="native" />
</id>
<property column="Code" name="Code" />
<property column="Name" name="Name" />
<property column="IsActive" name="IsActive" />
<bag name="DepartmentItems" table="b_Department">
<key column="FacultyID"/>
<one-to-many class="Department" />
</bag>
</class>
</hibernate-mapping>
Department.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping
xmlns="urn:nhibernate-mapping-2.2"
namespace="UserManagememntApplication.BO"
assembly="UserManagememntApplication.BO" >
<class name="Department" table="b_Department">
<id column="ID" name="ID" type="System.Int32" >
<generator class="native" />
</id>
<property column="Code" name="Code" />
<property column="Name" name="Name" />
<property column="IsActive" name="IsActive" />
<many-to-one name="Faculty" class="Faculty" column="FacultyID" unique="true" />
<bag name="TeacherItems" table="b_Teacher">
<key column="DepartmentID"/>
<one-to-many class="Teacher" />
</bag>
</class>
</hibernate-mapping>
b_Faculty
CREATE TABLE [dbo].[b_Faculty](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Code] [varchar](50) NOT NULL,
[Name] [varchar](50) NOT NULL,
[IsActive] [bit] NOT NULL,
CONSTRAINT [PK_b_Faculty] 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]
b_Department
CREATE TABLE [dbo].[b_Department](
[ID] [int] IDENTITY(1,1) NOT NULL,
[FacultyID] [int] NOT NULL,
[Code] [varchar](50) NOT NULL,
[Name] [varchar](50) NOT NULL,
[IsActive] [bit] NOT NULL,
CONSTRAINT [PK_b_Department] 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]
Edit:
Faculty.cs
public class Faculty : BusinessObject<Faculty>
{
public virtual string Code { get; set; }
public virtual string Name { get; set; }
public virtual bool IsActive { get; set; }
public virtual IEnumerable<Department> DepartmentItems { get; set; }
}
Department.cs
public class Department : BusinessObject<Department>
{
public virtual string Code { get; set; }
public virtual string Name { get; set; }
public virtual bool IsActive { get; set; }
public virtual Faculty Faculty { get; set; }
public virtual IEnumerable<Teacher> TeacherItems { get; set; }
}
BusinessObject.cs
public abstract class BusinessObject<T> : IBusinessObject where T : BusinessObject<T>
{
public int ID { get; set; }
public static bool operator ==(BusinessObject<T> item1, BusinessObject<T> item2)
{
bool same = false;
if (!object.ReferenceEquals(item1, null) && !object.ReferenceEquals(item2, null))
{
if (item1.ID == item2.ID)
{
same = true;
}
}
else
{
if (object.ReferenceEquals(item1, null) && object.ReferenceEquals(item2, null))
{
same = true;
}
}
return same;
}
public static bool operator !=(BusinessObject<T> item1, BusinessObject<T> item2)
{
return !(item1 == item2);
}
public override bool Equals(object obj)
{
//If "obj" is null, they are obviously not equal.
if (obj == null)
{
return false;
}
//If the objects are the same instance, they must be equal.
if (Object.ReferenceEquals(this, obj))
{
return true;
}
//If the objects are not the same type, they cannot be equal.
if (this.GetType() != obj.GetType())
{
return false;
}
T objCustomer = (T)obj;
if (this.ID > 0 && objCustomer.ID > 0)
{
if (this.ID.Equals(objCustomer.ID))
{
return true;
}
}
return false;
}
public override int GetHashCode()
{
if (this.ID <= 0)
{
return base.GetHashCode();
}
else
{
return ID.GetHashCode();
}
}
}
FacultyRepository.cs
public class FacultyRepository : Repository<Faculty>
{
}
DepartmentRepository.cs
public class DepartmentRepository : Repository<Department>
{
}
Repository.cs
public class Repository<T> : IRepository<T>
{
ISession _session;
public Repository()
{
_session = SessionFactory.GetOpenSession();
}
public T Get(object id)
{
T obj = default(T);
try
{
if (!_session.Transaction.IsActive)
{
_session.BeginTransaction();
obj = (T)_session.Get<T>(id);
_session.Transaction.Commit();
_session.Flush();
}
else
{
throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
catch (Exception ex)
{
_session.Transaction.Rollback();
_session.Clear();
throw ex;
}
return obj;
}
public IEnumerable<T> Get(string fieldName, object fieldValue)
{
IEnumerable<T> list = null;
try
{
if (!_session.Transaction.IsActive)
{
_session.BeginTransaction();
list = (IEnumerable<T>)_session.CreateCriteria(typeof(T))
.Add(new NHibernate.Expression.EqExpression(fieldName, fieldValue))
.List<T>();
_session.Transaction.Commit();
_session.Flush();
}
else
{
throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
catch (Exception ex)
{
_session.Transaction.Rollback();
_session.Clear();
throw ex;
}
return list;
}
public IEnumerable<T> Get()
{
IEnumerable<T> list = null;
try
{
if (!_session.Transaction.IsActive)
{
_session.BeginTransaction();
list = (IEnumerable<T>)_session.CreateCriteria(typeof(T)).List<T>();
_session.Transaction.Commit();
_session.Flush();
}
else
{
throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
catch (Exception ex)
{
_session.Transaction.Rollback();
_session.Clear();
throw ex;
}
return list;
}
public void SaveOrUpdate(T obj)
{
try
{
if (!_session.Transaction.IsActive)
{
_session.BeginTransaction();
_session.SaveOrUpdateCopy(obj);
_session.Transaction.Commit();
_session.Flush();
}
else
{
throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
catch (Exception ex)
{
_session.Transaction.Rollback();
_session.Clear();
throw ex;
}
}
public void SaveOrUpdate(IEnumerable<T> objs)
{
try
{
if (!_session.Transaction.IsActive)
{
_session.BeginTransaction();
foreach (T obj in objs)
{
_session.SaveOrUpdate(obj);
}
_session.Transaction.Commit();
_session.Flush();
}
else
{
throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
catch (Exception ex)
{
_session.Transaction.Rollback();
_session.Clear();
throw ex;
}
}
public void Delete(T obj)
{
try
{
if (!_session.Transaction.IsActive)
{
_session.BeginTransaction();
_session.Delete(obj);
_session.Transaction.Commit();
_session.Flush();
}
else
{
throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
catch (Exception ex)
{
_session.Transaction.Rollback();
_session.Clear();
throw ex;
}
}
public void Delete(IEnumerable<T> objs)
{
try
{
if (!_session.Transaction.IsActive)
{
_session.BeginTransaction();
foreach (T obj in objs)
{
_session.Delete(obj);
}
_session.Transaction.Commit();
_session.Flush();
}
else
{
throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
catch (Exception ex)
{
_session.Transaction.Rollback();
_session.Clear();
throw ex;
}
}
public void DeleteAll()
{
try
{
if (!_session.Transaction.IsActive)
{
_session.BeginTransaction();
DetachedCriteria criterion = DetachedCriteria.For<T>();
IList<T> list = criterion.GetExecutableCriteria(_session).List<T>();
foreach (T item in list)
{
_session.Delete(item);
}
_session.Transaction.Commit();
_session.Flush();
}
else
{
throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
}
}
catch (Exception ex)
{
_session.Transaction.Rollback();
throw ex;
}
}
public void Dispose()
{
if (_session != null)
{
_session.Clear();
_session.Close();
_session = null;
}
}
}
SessionFactory.cs
public class SessionFactory
{
private static ISessionFactory _sessionFactory = null;
private SessionFactory(){}
static SessionFactory()
{
if (_sessionFactory == null)
{
Configuration configuration = new Configuration();
configuration.Configure();
_sessionFactory = configuration.BuildSessionFactory();
}
}
public static ISession GetOpenSession()
{
return _sessionFactory.OpenSession();
}
}
This is all I have.
An extremely wild guess. Could you try to run your code without the equality comparers and the Equals
implementation and see whether that helps, so with the following implementation:
public abstract class BusinessObject<T> : IBusinessObject where T : BusinessObject<T>
{
public int ID { get; set; }
}
Another thing you may want to try is to set the ID
to private:
public abstract class BusinessObject<T> : IBusinessObject where T : BusinessObject<T>
{
public int ID { get; private set; }
}
See what the effect of that is.
这篇关于NHibernate的对象ID将返回不正确的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!