使用Fluent nHibernate通过属性来浮动对象子集合
本文关键字:对象 子集合 属性 Fluent nHibernate 使用 | 更新日期: 2023-09-27 17:57:40
请原谅我的无知,我是nHibernate的新手,在尝试使用nHibernat查询筛选子集合时遇到了概念问题
我的对象模型包含两个实体,用户和任务设置如下
public class User
{
public User()
{
this.Tasks = new List<Task>();
}
public User(int id): this()
{
this.Id = id;
}
public virtual int Id { get; private set; }
public virtual IList<Task> Tasks { get; set; }
}
public class Task
{
public Task() { }
public Task(int id, bool active): this()
{
this.Id = id;
this.Active = active;
}
public virtual int Id { get; set; }
public virtual bool Active { get; set; }
}
我的nHibernate映射如下
public class UserMap: ClassMap<User>
{
public UserMap()
{
Table("user");
Id(x => x.Id);
HasMany(x => x.Tasks);
}
}
public class TaskMap : ClassMap<Task>
{
public TaskMap()
{
Table("task");
Id(x => x.Id);
Map(x => x.Active);
}
}
我的数据库有两个表"任务"answers"用户",我已经填写了
SELECT * FROM task;
+----+--------+---------+
| Id | Active | User_id |
+----+--------+---------+
| 1 | 1 | 3 |
| 2 | 1 | 3 |
| 3 | 1 | 3 |
| 4 | 0 | 3 |
| 5 | 0 | 3 |
| 6 | 1 | 1 |
| 7 | 1 | 1 |
| 8 | 1 | 1 |
| 9 | 0 | 1 |
| 10 | 0 | 1 |
+----+--------+---------+
10 rows in set
SELECT * FROM user;
+----+
| Id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+----+
5 rows in set
我想做的是运行一个查询,返回一个特定用户,该用户的"任务"集合中只有活动任务
var query = QueryOver.Of<User>()
.Where(u => u.Id == 3)
.JoinQueryOver<Task>(x => x.Tasks)
.Where(t => t.Active == true);
var results = dataProvider.ExcecuteQuery<User>(query);
当我执行这个查询时,我希望返回一个在其Tasks集合中有3个Task对象的单个用户对象,而我得到的是同一任务对象(Task.Id=3)的3个副本,所有这些对象在各自的集合中都有全部5个Task。
我试图做的事情实际上可行吗?还是应该只是查询Task实体?
我希望情况并非如此,因为能够看到用户的活动任务而不必手动过滤会很好。
首先,我想把它分解为两个查询。在制作主细节时,获取用户实体,然后为用户获取任务可能更有意义。。。
我使用QueryOver.Of<T>()
不是很好,但这里有一种使用session.QueryOver<T>()
:的方法
var users = session.QueryOver<User>()
.Where(u => u.Id == 3)
.Fetch(o => o.Tasks)
.Lazy()
.SingleOrDefault();
users.Tasks.TakeWhile(o => o.Active);
我认为你也可以使用过滤器,但这听起来不像你想做的。我不认为QueryOver.Of<T>()
能满足你的要求,因为断开连接的查询需要一个过滤器来正确地拉回子元素。
您可以在List()
方法之前应用.TransformUsing( Transformers.DistinctRootEntity)
,只获得1个用户对象。之后,您看到的是向数据库发出另一个查询,以获取该用户的任务列表(不过滤活动任务),这就是延迟加载的含义。在数据库配置部分中添加.ShowSql().FormatSql()
,查看发生了什么。
您也可以将此属性添加到Task
类中
public virtual User User { set; get; }
有这样的查询:(你首先想要什么)
var list = session.QueryOver<Task>()
.Fetch(t=>t.User).Eager
.Where(t => t.Active && t.User.Id==3)
.TransformUsing(Transformers.DistinctRootEntity)
.List();