仅从表中选择少数列

本文关键字:数列 选择 | 更新日期: 2023-09-27 18:02:54

我在使用c#、nhibernate和link时遇到了问题。在下面的示例中,我在BrandTable中执行SELECT,但我只需要"Name"answers"Id"列。但它总是对表的所有列执行select。使用EntityFramework,下面相同的代码生成一个只有这两列的select。

如何在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();
        }

仅从表中选择少数列

你不能在QueryOver中使用查询推导式,因为它不是Linq提供程序。在你的例子中,你实际上选择了所有的记录,然后使用LINQ到对象。添加NHibernate。并将查询重写为

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

这是一个使用投影的例子:

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 aggregate

[编辑]此外,目前在缓存标准预测时存在一个错误。(如果尝试缓存查询,会得到一个异常)https://nhibernate.jira.com/browse/NH-1090(/编辑)


相关文章:

NHibernate标准:如何排除某些映射属性/集合?

使用条件查询时只检索特定列吗?

LINQ-NHibernate -为一个复杂的对象只选择几个字段(包括一个集合)


要使你的查询是重构安全的(没有'魔法字符串'),你可以实现这样的东西:

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);

您也可以在NH中使用QueryOver来完成此操作。以下摘自http://nhforge.org/blogs/nhibernate/archive/2009/12/17/queryover-in-nh-3-0.aspx

预测

可以使用.Select方法添加根类型属性的简单投影,该方法可以接受多个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>();

在上面的链接中还有几个关于如何使用投影的例子。

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

    用你想要的字段创建一个小类:例子:

 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()});
    

    在示例中,Lead是我们想要提取信息的实体。注意,目的地与目标类LeadInformation的类型相同。这将返回目标类LeadInformation的可查询列表,其中只有源域类的两列。