2011-07-21 36 views
4

我在使用c#,nhibernate和链接时遇到了问题。在下面的例子中,我在BrandTable中做了一个SELECT,但我只需要“Name”和“Id”列。 但它总是对表格的所有列进行选择。 使用EntityFramework,下面的代码只生成一个只有这两列的选择。只从表中选择几列

如何在nhibernate中做到这一点?

using (ISession session = MyConnection.GetCurrentSession()) 
     { 
      var brands = from b in session.QueryOver<BrandTable>().List() 
           orderby b.Name 
           select new Brand {Id = b.id, Name = b.Name}; 

      return brands.ToList(); 
     } 
+0

您正在订购并在内存中应用投影,这就是为什么不起作用(.List()方法选择所有记录 – Vasea

回答

4

这是一个例子使用投影:

List results = session.CreateCriteria<BrandTable>() 
.SetProjection(Projections.ProjectionList() 
    .Add(Projections.Id(), "Id") 
    .Add(Projections.Property("Name"), "Name") 
) 
.SetResultTransformer(Transformers.AliasToBean<BrandTable>()); // edit - don't forget the result transformer! 
.List(); 

此处作为一例使用QueryOver:

NHibernate QueryOver select entity and aggregates

[编辑] 也,目前高速缓存的ICriteria时的错误预测。 (如果您尝试缓存查询,你会得到一个例外) https://nhibernate.jira.com/browse/NH-1090 [/编辑]


Releted帖子:

NHibernate Criteria: howto exclude certain mapped properties/collections?

Only retrieve specific columns when using Critera queries?

LINQ-NHibernate - Selecting only a few fields (including a Collection) for a complex object


,使您的查询重构安全的(没有“魔法字符串”),可以实现像这样:

public static class ObjectExtensions 
{ 
    public static string NameOf<T>(this T target, Expression<Func<T, object>> propertyExpression) 
    { 
     MemberExpression body = null; 
     if (propertyExpression.Body is UnaryExpression) 
     { 
      var unary = propertyExpression.Body as UnaryExpression; 
      if (unary.Operand is MemberExpression) 
       body = unary.Operand as MemberExpression; 
     } 
     else if (propertyExpression.Body is MemberExpression) 
     { 
      body = propertyExpression.Body as MemberExpression; 
     } 
     if (body == null) 
      throw new ArgumentException("'propertyExpression' should be a member expression"); 

     // Extract the right part (after "=>") 
     var vmExpression = body.Expression as ConstantExpression; 

     // Extract the name of the property 
     return body.Member.Name; 
    } 

} 

使用这样的:

MyEntity entity = null; // don't need a 'valid' instance. 
string propName = entity.NameOf(x => x.SomePropertyName); 
+0

第二个示例不起作用,它发送所有列以查询 –

+0

第二个示例doesn没有工作,因为它正在过滤内存中的集合 – Vasea

+0

我更新了帖子!thx! – danyolgiax

1

您也可以做到这一点NH中的QueryOver。下面是从http://nhforge.org/blogs/nhibernate/archive/2009/12/17/queryover-in-nh-3-0.aspx

预测采取

根类型的属性的简单凸起可以使用。选择方法,其可以利用多个Lambda表达式参数被添加:

IList selection = 
    session.QueryOver<Cat>() 
     .Select(
      c => c.Name, 
      c => c.Age) 
     .List<object[]>(); 

由于这个查询没有更长的返回Cat,返回类型必须明确指定。

IList<int> ages = 
    session.QueryOver<Cat>() 
     .Select(c => c.Age) 
     .List<int>(); 

有如何在上面的链接使用突起几个例子:如果单个属性被投影,则返回类型可以利用来指定。

6

对于QueryOver,您不能使用查询解析,因为它不是Linq提供程序。在你的例子中,你实际上选择了所有记录,然后使用LINQ to Objects。添加NHibernate。LINQ的命名空间到您的文件,并改写查询作为

from b in session.Query<BrandTable>() 
orderby b.Name 
select new Brand {Id = b.id, Name = b.Name}; 
0

您可以使用以下步骤中选择了一个域的一些列:

  1. 创建一个小的类,你想要的字段: 例子:

private class LeadInformation 
    { 
      public string Id { get; set; } 
      public DateTime AdmissionDate { get; set; } 
    } 

  • 查询要提取的信息在哪里域实体
  • 
    IQueryable leads = 
           repository.Query() 
           .Where(x => x.AdmissionRepUserObj.ID.ToString() == filter.UserId 
            ).Select(lead => new LeadInformation 
            {AdmissionDate = lead.DateApplied.Value, 
            Id = lead.ID.ToString()}); 
    
    

    在以身作则的是,我们要提取信息的实体。注意目标是相同类型的目标类LeadInformation。 这会返回目标类LeadInformation的可查询列表,只有源域类的两列。