【问题标题】:How to "Select" with nhibernate queryover如何使用休眠查询“选择”
【发布时间】:2011-08-20 20:22:24
【问题描述】:

我想使用查询返回给我一个对象

 public class TaskMap : ClassMap<Task>
    {
        public TaskMap()
        {
            Table("Tasks");
            Id(x => x.TaskId);
            Map(x => x.TaskName).NvarcharWithMaxSize().Not.Nullable();
            Map(x => x.Description).NvarcharWithMaxSize();
            Map(x => x.DueDate).Not.Nullable();
            HasMany(x => x.PersonalTaskReminders).Inverse();
            HasMany(x => x.TaskReminders).Inverse();
            References(x => x.Course).Not.Nullable();
            HasMany(x => x.CompletedTasks);

        }
    }



[Serializable()]
public class Task
{
    public virtual int TaskId { get; private set; }
    public virtual string TaskName { get;  set; }
    public virtual string Description { get; set; }
    public virtual DateTime DueDate { get; set; }
    public virtual IList<PersonalTaskReminder> PersonalTaskReminders { get; set; }
    public virtual IList<TaskReminder> TaskReminders { get; set; }
    public virtual IList<CompletedTask> CompletedTasks { get; set; }
    public virtual Course Course { get; set; }

    public Task()
    {
        PersonalTaskReminders = new List<PersonalTaskReminder>();
        TaskReminders = new List<TaskReminder>();
        CompletedTasks = new List<CompletedTask>();
    }

}
     public class PlannerTask
{
    public int TaskId { get; set; }
    public string TaskName { get; set; }
    public string Description { get; set; }
    public DateTime DueDate { get; set; }
    public List<PersonalTaskReminder> PersonalTaskReminders { get; set; }
    public List<TaskReminder> TaskReminders { get; set; }
    public Course Course { get; set; }
    public bool IsCompleted { get; set; }


}

试试 1

Task tAlias = null;
        PlannerTask plannerTask = null;
        List<PlannerTask> result = session.QueryOver<Task>(() => tAlias)
            .Select(x => x.Course).TransformUsing(Transformers.AliasToBean<PlannerTask>())               
            .List<PlannerTask>().ToList();

结果:1​​88 条记录,课程对象全部为空。

试试 2

Task tAlias = null;
            PlannerTask plannerTask = null;
            List<PlannerTask> result = session.QueryOver<Task>(() => tAlias)
                         .Select(Projections.Property(() => tAlias.TaskId).WithAlias(() => plannerTask.TaskId),
                         Projections.Property(() => tAlias.TaskName).WithAlias(() => plannerTask.TaskName),
                         Projections.Property(() => tAlias.DueDate).WithAlias(() => plannerTask.DueDate),
                         Projections.Property(() => tAlias.Description).WithAlias(() => plannerTask.Description),
                         Projections.Property(() => tAlias.PersonalTaskReminders).WithAlias(() => plannerTask.PersonalTaskReminders),
                         Projections.Property(() => tAlias.TaskReminders).WithAlias(() => plannerTask.PersonalTaskReminders),
                         Projections.Property(() => tAlias.Course).WithAlias(() => plannerTask.Course))
                .TransformUsing(Transformers.AliasToBean<PlannerTask>())               
                .List<PlannerTask>().ToList();

结果:1​​88 门课程的所有属性都有几乎相同的错误

'((new System.Collections.Generic.Mscorlib_CollectionDebugView<Domain.PlannerTask>(result)).Items[0].Course).CoursePermissions' threw an exception of type 'NHibernate.ObjectNotFoundException'

试试 3

 Task tAlias = null;
        PlannerTask plannerTask = null;
        List<PlannerTask> result = session.QueryOver<Task>(() => tAlias)
             .Select(Projections.Property(() => tAlias.TaskId).WithAlias(() => plannerTask.TaskId),
             Projections.Property(() => tAlias.TaskName).WithAlias(() => plannerTask.TaskName),
             Projections.Property(() => tAlias.DueDate).WithAlias(() => plannerTask.DueDate),
             Projections.Property(() => tAlias.Description).WithAlias(() => plannerTask.Description),
             Projections.ProjectionList().Add(Projections.Property(()=> tAlias.PersonalTaskReminders).WithAlias(() => plannerTask.PersonalTaskReminders)),
             Projections.ProjectionList().Add(Projections.Property(()=> tAlias.TaskReminders).WithAlias(() => plannerTask.PersonalTaskReminders)),
             Projections.Property(() => tAlias.Course).WithAlias(() => plannerTask.Course))
            .TransformUsing(Transformers.AliasToBean<PlannerTask>())               
            .List<PlannerTask>().ToList();


SELECT this_.TaskId      as y0_,
       this_.TaskName    as y1_,
       this_.DueDate     as y2_,
       this_.Description as y3_,
       this_.TaskId      as y4_,
       this_.TaskId      as y4_,
       this_.CourseId    as y4_
FROM   Tasks this_

结果:

CoursePermissions = '((Castle.Proxies.CourseProxy)((new System.Collections.Generic.Mscorlib_CollectionDebugView<PlannerTask>(result)).Items[0].Course)).CoursePermissions' threw an exception of type 'NHibernate.ObjectNotFoundException'

试试 4

试试 4

 Task tAlias = null;
        PlannerTask plannerTask = null;
        List<PlannerTask> result = session.QueryOver<Task>(() => tAlias)
             .Select(Projections.Property(() => tAlias.TaskId).WithAlias(() => plannerTask.TaskId),
             Projections.Property(() => tAlias.TaskName).WithAlias(() => plannerTask.TaskName),
             Projections.Property(() => tAlias.DueDate).WithAlias(() => plannerTask.DueDate),
             Projections.Property(() => tAlias.Description).WithAlias(() => plannerTask.Description),
             Projections.Property(() => tAlias.Course).WithAlias(() => plannerTask.Course))
            .TransformUsing(Transformers.AliasToBean<PlannerTask>())               
            .List<PlannerTask>().ToList();


SELECT this_.TaskId      as y0_,
       this_.TaskName    as y1_,
       this_.DueDate     as y2_,
       this_.Description as y3_,
       this_.CourseId    as y4_
FROM   Tasks this_

有效。我可以访问课程对象中的所有内容。

好像有问题

tAlias.PersonalTask​​Reminders 和 tAlias.TaskReminders。如果我删除这些课程将呈现正常。

我不明白为什么。

【问题讨论】:

  • 不太清楚你想做什么。
  • @Mauricio Scheffer - 我正在尝试进行选择,将结果放入 PlannerTask 对象的集合中,但每个 PlannerTask 对象中的 Course 对象都会抛出异常。
  • 您能发布为 Try 4 和 Try 3 生成的 SQL 吗?
  • @Vadmin - 我只是通过调试器来获得它吗?
  • 我开始写一个答案,但我质疑为什么这甚至是一个要求。为什么您不能获取常规任务对象,然后使用自定义解决方案或 AutoMapper 或 ValueInjecter 之类的东西将它们映射到 PlannerTask 对象?从您发布的 SQL 来看,它似乎没有进行任何连接,因此没有创建正确的集合。

标签: nhibernate queryover


【解决方案1】:

我认为问题在于您正在尝试投影课程代理对象。投影用于平面数据传输对象。您可以声明此视​​图所需的课程属性。

public class PlannerTask
{
    public int TaskId { get; set; }
    public string TaskName { get; set; }
    public string Description { get; set; }
    public DateTime DueDate { get; set; }
    //flatten Course object
    public int CourseId { get; set; }
    public int CourseName { get; set; }
    public bool IsCompleted { get; set; }
}

选择列表可以简化一点...

PlannerTask plannerTask = null;
Course courseAlias = null;

List<PlannerTask> result = session.QueryOver<Task>()
    .JoinAlias(x => x.Course, () => courseAlias)
    .SelectList(list => list
        .Select(x => x.TaskId).WithAlias(() => plannerTask.TaskId)
        .Select(x => x.TaskName).WithAlias(() => plannerTask.TaskName)
        .Select(x => x.DueDate).WithAlias(() => plannerTask.DueDate)
        .Select(x => x.Description).WithAlias(() => plannerTask.Description)
        .Select(x => x.Course.Id).WithAlias(() => plannerTask.CourseId))
        .Select(x => courseAlias.Name).WithAlias(() => plannerTask.CourseName))
    .TransformUsing(Transformers.AliasToBean<PlannerTask>())               
    .List<PlannerTask>();

【讨论】:

  • 我不确定代理对象是什么,但如果我只有“Course”而不是“PersonalTask​​Reminders / TaskReminders”但是当我添加这两个时它会失败,为什么它会正确投影?
  • 您不能投影像Course 这样的映射对象。当您尝试这样做时,您会得到这种僵尸代理对象,当您访问延迟加载的属性时会抛出 NHibernate.ObjectNotFoundException
  • 我会理解,如果不是因为“尝试 4”有效。那么,当我忽略其他两个映射对象(PersonalTask​​Reminders/TaskReminders)时,为什么它可以做到这一点。如果“尝试 4”不起作用,那么它是有道理的,但既然它起作用了,我就会感到困惑。
  • 哦,这行得通吗?这有点酷,我以前从未尝试过。它是否只选择课程 ID,然后延迟加载课程对象的其余部分?那么,这些错误只会在您投影集合时引起?
  • 我将不得不检查但没有抛出错误。当我保护这些集合时,我只会收到这些错误。它们以某种方式影响 Course 对象。它们似乎也总是为空。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-24
  • 2018-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-16
相关资源
最近更新 更多