通过subentity的平均值查询NHibernate中的实体

时间:2009-01-17 12:54:57

标签: nhibernate

我有一个像这样的实体产品:

[Class(0, Name = "Product", Table = "Products")]
public class Product
{
    private readonly ISet<ProductPropertyValue> _productPropertyValues;
    private readonly ISet<ProductImage> _productImages;
    private readonly ISet<ProductComment> _productComments;
    private readonly IList<Category> _categories;
    private readonly ISet<Rate> _rates;

    public Product()
    {
        _productPropertyValues = new HashedSet<ProductPropertyValue>();
        _productImages = new HashedSet<ProductImage>();
        _productComments = new HashedSet<ProductComment>();
        _categories = new List<Category>();
        _rates = new HashedSet<Rate>(); ;
    }

    [Id(0, Name = "ProductId", Type = "Int32", Column = "ProductID")]
    [Generator(1, Class = "native")]
    public virtual Int32 ProductId { get; set; }

    [Property(0, Name = "Description", Column = "Description", Type = "string")]
    public virtual String Description { get; set; }

    [Property(0, Name = "ShortDescription", Column = "ShortDescription", Type = "string")]
    public virtual String ShortDescription { get; set; }

    [Property(0, Name = "ProductName", Column = "ProductName", Type = "string")]
    public virtual String ProductName { get; set; }

    [Property(0, Name = "UnitPrice", Column = "UnitPrice", Type = "double")]
    public virtual double UnitPrice { get; set; }

    [Property(0, Name = "UnitsInStock", Column = "UnitsInStock", Type = "int")]
    public virtual int UnitsInStock { get; set; }

    [Property(0, Name = "MainImagePath", Column = "MainImagePath", Type = "string")]
    public virtual String MainImagePath { get; set; }

    [Property(0, Name = "NumberOfSales", Column = "NumberOfSales", Type = "int")]
    public virtual int NumberOfSales { get; set; }

    [Property(0, Name = "NumberOfViews", Column = "NumberOfViews", Type = "int")]
    public virtual int NumberOfViews { get; set; }

    [Property(0, Name = "IsSpecial", Column = "IsSpecial", Type = "boolean")]
    public virtual bool IsSpecial { get; set; }

    [Property(0, Name = "AdditionDate", Column = "AdditionDate", Type = "DateTime")]
    public virtual DateTime AdditionDate { get; set; }

    [Property(Name = "Enabled", Column = "Enabled", Type = "boolean")]
    public virtual bool Enabled { get; set; }

    [Bag(0, Name = "Categories", Lazy = true, Table = "Products_Categories",
        Access = "field.camelcase-underscore", Cascade = "none")]
    [Key(1, Column = "ProductID")]
    [ManyToMany(2, Class = "Category", Column = "CategoryID")]
    public virtual ReadOnlyCollection<Category> Categories
    {
        get { return new ReadOnlyCollection<Category>(_categories); }
    }

    [Set(0, Name = "ProductComments", Lazy = true, Access = "field.camelcase-underscore",
        Cascade = "save-update", Inverse = true)]
    [Key(1, Column = "ProductID")]
    [OneToMany(2, Class = "ProductComment")]
    public virtual ReadOnlyCollection<ProductComment> ProductComments
    {
        get { return new ReadOnlyCollection<ProductComment>(new List<ProductComment>(_productComments)); }
    }

    [Set(0, Name = "ProductImages", Lazy = true, Access = "field.camelcase-underscore",
        Cascade = "save-update")]
    [Key(1, Column = "ProductID")]
    [OneToMany(2, Class = "ProductImage")]
    public virtual ReadOnlyCollection<ProductImage> ProductImages
    {
        get { return new ReadOnlyCollection<ProductImage>(new List<ProductImage>(_productImages)); }
    }

    [Set(0, Name = "ProductPropertyValues", Lazy = true, Access = "field.camelcase-underscore",
        Cascade = "save-update")]
    [Key(1, Column = "ProductID")]
    [OneToMany(2, Class = "ProductPropertyValue")]
    public virtual ReadOnlyCollection<ProductPropertyValue> ProductPropertyValues
    {
        get { return new ReadOnlyCollection<ProductPropertyValue>(new List<ProductPropertyValue>(_productPropertyValues)); }
    }

    [Set(0, Name = "Rates", Lazy = true, Access = "field.camelcase-underscore",
        Cascade = "save-update")]
    [Key(1, Column = "ProductID")]
    [OneToMany(2, Class = "Rate")]
    public virtual ReadOnlyCollection<Rate> Rates
    {
        get { return new ReadOnlyCollection<Rate>(new List<Rate>(_rates)); }
    }

    /// <summary>
    /// Gets everage rate.
    /// </summary>
    /// <value>The everage rate.</value>
    public double AverageRate
    {
        get
        {
            if (_rates.Count != 0)
            {
                return _rates.Average(x => x.Value);    
            }
            return 0;
        }
    }

    /// <summary>
    /// Gets rounded average rate.
    /// </summary>
    /// <value>The rounded average rate.</value>
    public Int32 AverageRateRounded
    {
        get
        {
            return (int)Math.Round(AverageRate);
        }
    }

    /// <summary>
    /// Gets the number of votes.
    /// </summary>
    /// <value>The number of votes.</value>
    public Int32 NumberOfVotes
    {
        get
        {
            return _rates.Count;
        }
    }


    /// <summary>
    /// Add new comment to current product
    /// </summary>
    /// <param name="commentToAdd">Comment to add</param>
    public virtual void AddComment(ProductComment commentToAdd)
    {
        if (commentToAdd != null)
        {
            if (!_productComments.Contains(commentToAdd))
            {
                _productComments.Add(commentToAdd);
            }
        }
    }

    /// <summary>
    /// Delete comment from current product 
    /// </summary>
    /// <param name="commentToDelete"></param>
    public virtual void DeleteComment(ProductComment commentToDelete)
    {
        if (commentToDelete != null)
        {
            if (_productComments.Contains(commentToDelete))
            {
                _productComments.Remove(commentToDelete);
            }
        }
    }


    /// <summary>
    /// Add image to current product 
    /// </summary>
    /// <param name="imageToAdd">Image to add</param>
    public virtual void AddImage(ProductImage imageToAdd)
    {
        if (imageToAdd != null)
        {
            if (!_productImages.Contains(imageToAdd))
            {
                _productImages.Add(imageToAdd);
            }
        }
    }

    /// <summary>
    /// Delete image from current product
    /// </summary>
    /// <param name="imageToDelete">Image to delete</param>
    public virtual void DeleteImage(ProductImage imageToDelete)
    {
        if (imageToDelete != null)
        {
            if (_productImages.Contains(imageToDelete))
            {
                _productImages.Remove(imageToDelete);
            }
        }
    }


    /// <summary>
    /// Add property to current product
    /// </summary>
    /// <param name="valueToAdd">Value to add</param>
    public virtual void AddProrerty(ProductPropertyValue valueToAdd)
    {
        if (valueToAdd != null)
        {
            if (!_productPropertyValues.Contains(valueToAdd))
            {
                _productPropertyValues.Add(valueToAdd);
            }
        }
    }

    /// <summary>
    /// Delete property from current product
    /// </summary>
    /// <param name="valueToDelete">Value to delete</param>
    public virtual void DeleteProperty(ProductPropertyValue valueToDelete)
    {
        if (valueToDelete != null)
        {
            if (_productPropertyValues.Contains(valueToDelete))
            {
                _productPropertyValues.Remove(valueToDelete);
            }
        }
    }


    /// <summary>
    /// Adds rate to current product.
    /// </summary>
    /// <param name="rate">The rate.</param>
    public virtual void AddRate(Rate rate)
    {
        if (rate != null)
        {
            if (!_rates.Contains(rate))
            {
                _rates.Add(rate);
            }
        }
    }

    /// <summary>
    /// Deletes rate from product.
    /// </summary>
    /// <param name="rate">The rate.</param>
    public virtual void DeleteRate(Rate rate)
    {
        if (rate != null)
        {
            if (_rates.Contains(rate))
            {
                _rates.Remove(rate);
            }
        }
    }
}

和像这样的Rate实体:

[Class(0, Name = "Rate", Table = "Rates")]
public class Rate
{
    [CompositeId(1)]
    [KeyManyToOne(2, Name = "Product", Class = "Product", Column = "ProductId")]
    [KeyManyToOne(3, Name = "User", Class = "User", Column = "UserId")]
    public virtual Product Product { get; set; }

    public virtual User User { get; set; }

    [Property(0, Name = "Value", Column = "Value", Type = "Int32")]
    public virtual Int32 Value { get; set; }

}

我需要以DESC顺序获取所有平均评级的产品。此外,它应该可由Product的任何字段过滤,例如价格:1000美元至5000美元。 感谢。

2 个答案:

答案 0 :(得分:0)

应该主要考虑你的想法。

在HQL中:

select p
from Product p join p.Rates r
where (p.Price >= 1000 and p.Price <= 5000)
order by avg(r.Value) desc 

答案 1 :(得分:0)

我想玩一点,但我有点懒得设置一个小测试项目。

在任何情况下,如果你想获取这些产品,以概览或类似方式显示它们,我会使用Projections和AliasToBean转换器,以便NHibernate发出一个更简单的查询,并检索仅显示概览所需的值。 为了做到这一点,你将不得不创建另一个类的offcourse,它将保存将被检索的值。