【发布时间】:2014-02-01 12:15:31
【问题描述】:
我有以下物品:
public abstract class Event {
public virtual Guid Id { get; set; }
public virtual string Description { get; set; }
}
public class TeamEvent : Event {
public virtual Guid Id { get; set; }
public virtual Team Team { get; set; }
}
public class PersonEvent : Event {
public virtual Guid Id { get; set; }
public virtual Person Person { get; set; }
}
public class Team {
public virtual Guid Id { get; set; }
public virtual string Name { get; set; }
}
public class Person {
public virtual Guid Id { get; set; }
public virtual string Forename { get; set; }
public virtual string Surname { get; set; }
}
和映射:
<discriminator column="Discriminator"
not-null="true"
type="System.String"/>
<subclass
name="TeamEvent"
discriminator-value="TeamEvent">
<many-to-one name="Team" column="TeamId"/>
</subclass>
<subclass
name="PersonalEvent"
discriminator-value="PersonalEvent">
<many-to-one name="Person" column="PersonId"/>
</subclass>
</class>
<class name="Person" table="Persons">
<id name="Id">
<generator class="assigned"/>
</id>
<property name="Forename"/>
<property name="Surname"/>
</class>
<class name="Team" table="Teams">
<id name="Id">
<generator class="assigned"/>
</id>
<property name="TeamName"/>
</class>
我想做的是一个查询,该查询将在一个查询中获取所有事件,而不管基本类型如何,以填充 DTO,例如:
public class EventDTO {
public virtual Guid EventId { get; set; }
public virtual string EventDescription { get; set; }
public virtual Guid PersonId { get; set; }
public virtual string PersonForename { get; set; }
public virtual string PersonSurname { get; set; }
public virtual Guid TeamId { get; set; }
public virtual string TeamName { get; set; }
}
如果是人员事件,则团队字段为空,反之亦然。
在 SQL 中,我会执行以下操作:
Select * from Events
left join Team on Events.TeamId = Team.Id
left join Person on Events.Person = Person.Id
我无法在 QueryOver 中执行此操作,因为 Events c# 对象没有团队/人员的属性。我可以这样做:
var events = session.QueryOver<Event>
.Where ( /* insert my restrictions */ )
.Future<Event>();
var teamEvents = session.QueryOver<TeamEvent>
.Where ( /* insert my restrictions */ )
.Future<TeamEvent>();
var personEvents = session.QueryOver<PersonEvent>
.Where ( /* insert my restrictions */ )
.Future<PersonEvent>();
/* union the results in memory */
从这些查询返回的数据量应该能够将结果合并到内存中。我的问题是真的有更优雅的方法吗?无需执行三个单独的查询。
我应该指出,这只是我为突出显示我的问题而输入的一个简单示例,因此上述代码示例中可能存在一些拼写错误等。在现实世界的问题中,系统的其他部分取决于映射,因此更改架构/映射/对象不是一种选择。
虽然我更喜欢使用查询,但我不介意使用条件或 hql,如果可以在那里以更简单的方式进行操作的话。此外,此查询最多只会返回 20 行经常访问并因此存储在二级缓存中的实体,因此如果它使代码简单,即使 N + 1 也不是主要问题。
我还应该指出三个查询一个不那么简单的原因是因为每个查询需要复制 10 个限制,并且还有几个其他事件子类。
感谢您的帮助。
【问题讨论】:
标签: c# sql nhibernate queryover