使用 Fluent nHibernate 通过属性过滤对象子集合
请原谅我的无知,我是 nHibernate 的新手,并且在尝试使用 nHibernate 查询过滤子集合时遇到概念问题
我的对象模型包含两个实体 User 和 Task 设置如下
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);
}
}
我的数据库有我已经填充了两个表“任务”和“用户”
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 对象,而我得到的是同一任务对象的 3 个副本 (task.Id = 3),所有这些副本在各自的集合中都有所有 5 个任务。
我想要做的事情实际上是可能的还是我应该只查询任务实体?
我希望情况并非如此,因为如果能够看到用户活动的任务而不必费力进行手动过滤,那就太好了。
Please excuse my ignorance, I am new to nHibernate and am having a conceptual problem trying to filtering an child collection with an nHibernate query
My object model contains two entities User and Task set up like this
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; }
}
My nHibernate mappings for these are as follows
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);
}
}
My database has two tables 'task' and 'user' which I have filled thusly
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
What I am trying to do is run a query that returns a specific user with only the active tasks in its 'Tasks' collection
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);
When I execture this query I expect to get back a single user object with 3 Task objects in its Tasks collection, instead what I get is 3 copies of the same task object (task.Id = 3) all of which have all 5 Tasks in their respective collections.
Is what I am trying to do actually possible or should I just be querying on the Task entity instead?
I hope this is not the case as it would be nice to be able to just see a users active tasks without having to messing around with manual filtering.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,我想我会把它分成两个查询。在制作主从细节时,获取用户实体,然后获取用户的任务可能更有意义...
我不太擅长使用 QueryOver.Of(),但这里有一种使用
session.QueryOver()
的方法:我认为您也可以使用过滤器,但这听起来不像您想要做的。我认为 QueryOver.Of() 不能满足您的要求,因为断开连接的查询需要一个过滤器来正确拉回子元素。
First, I think I would break it up into two queries. In making a master-detail it might make more sense to get the user entities, then get the tasks for the users...
I'm not really good using
QueryOver.Of<T>()
, but here's one way to do it usingsession.QueryOver<T>()
:I think you can use filters too, but it didn't sound like what you wanted to do. I don't think
QueryOver.Of<T>()
does what you want, because the disconnected query would need a filter to correctly pull back the child elements.您可以在
List()
方法之前应用.TransformUsing( Transformers.DistinctRootEntity)
来仅获取 1 个用户对象。之后,您看到的是向数据库发出另一个查询以获取该用户的任务列表(不过滤活动任务),这就是延迟加载的含义。
在数据库配置部分添加
.ShowSql().FormatSql()
以查看发生了什么。您还可以将此属性添加到您的
Task
类中以进行如下查询:(您首先想要什么)
You can apply
.TransformUsing( Transformers.DistinctRootEntity)
beforeList()
method to get only 1 user object.After that what you are seeing is issuing another query to the database to get the list of tasks of that user (without filtering the active ones) and this is the meaning of lazy loading.
Add
.ShowSql().FormatSql()
in your db config section to see what's happening.Also you can add this property to your
Task
classTo have queries like this: (what you want in the first place)