0

インターネット上のいくつかのフォーラムを調べても解決できなかった一般的な問題があります。

ASP.NET WebAPI を使用するレストラン評価アプリケーションがあります。このアプリには、Restaurant テーブルと Comments テーブルの 2 つのテーブルがあります。各レストランには複数のコメントがあり、各コメントには評価値があります。私は WebAPI にメソッドをまとめて、レストランテーブルから詳細を取得し、コメントテーブルを調べて各レストランの平均評価値を取得しようとしています。これまでの私の試みは以下のコードにありますが、うまくいきません。集計関数、平均関数、ネストされたクエリ、結合などを使用してみましたが、それでも平均値を取得できませんでした。誰かが助けてくれたらありがたいです?

public IQueryable<RestaurantView> GetRestaurants(string All)
    {
        var query = from x in db.Restaurants
                    select new RestaurantView
                    {
                        RestaurantID = x.RestaurantID,
                        RestaurantName = x.RestaurantName,
                        RestaurantDecription = x.RestaurantDecription
                        RestaurantRatingAverage = (from a in db.Restaurants
                         join b in db.Comments on a.RestaurantID equals b.CommentsRestaurantID into z
                         from c in z
                         group c by c.CommentsRestaurantID into g
                         select new
                         {
                            RatingAverage = Convert.ToDouble(g.Average(a => a.CommentsRating))
                         };)
                    };


        return query;
    }

更新: ジョナサンのテクニックを使用する (以下を参照)

public IQueryable<RestaurantView> GetRestaurants(string All)
    {
        var query = from x in db.Restaurants
                    select new RestaurantView
                    {
                        RestaurantID = x.RestaurantID,
                        RestaurantName = x.RestaurantName,
                        RestaurantDecription = x.RestaurantDecription,
                        RestaurantRatingAverage = (from a in db.Comments
                   where a.CommentsRestaurantID.Equals(x.RestaurantID)select a.CommentsRating).Average()
                    };


        return query;
    }

しかし、私は今次の例外を受け取ります

 An error has occurred.","ExceptionMessage":"The cast to value type 'Double' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type."
4

1 に答える 1

1

LINQPadで実行できる例を次に示します。

編集: サブクエリの null の処理を​​表示するように更新

void Main()
{
    var restaurants = new List<Restaurant>();
    restaurants.Add(new Restaurant(1, "McDonalds"));
    restaurants.Add(new Restaurant(2, "Wendy's"));
    restaurants.Add(new Restaurant(3, "KFC"));

    var comments = new List<Comment>();
    comments.Add(new Comment(1, 1, "I love clowns!", 9.5));
    comments.Add(new Comment(2, 1, "Disgusting", 1.0));
    comments.Add(new Comment(3, 1, "Average", 5.0));
    comments.Add(new Comment(4, 2, "Hmmm tasty", 8.5));
    comments.Add(new Comment(5, 2, "Yuck", 4.0));

    // Edit - removed comment for KFC, updated code below to handle nulls
    var restaurantsWithRatings = restaurants.Select(r => new {
            RestaurantId = r.RestaurantId,
            Name = r.Name,
            Rating = (
                comments.Where(c => c.RestaurantId == r.RestaurantId)
                    .Select(c => c.Rating)
                    .DefaultIfEmpty(0)
            ).Average()
        });

    foreach(var r in restaurantsWithRatings)
        Console.WriteLine("{0}: {1}", r.Name, r.Rating);
}

class Restaurant
{
    public Restaurant(int restaurantId, string name)
    {
        RestaurantId = restaurantId;
        Name = name;
    }

    public int RestaurantId { get; set; }
    public string Name { get; set; }
}

class Comment
{
    public Comment(int commentId, int restaurantId, string message, double rating)
    {
        CommentId = commentId;
        RestaurantId = restaurantId;
        Message = message;
        Rating = rating;
    }

    public int CommentId { get; set; }
    public int RestaurantId { get; set; }
    public string Message { get; set; }
    public double Rating { get; set; }
}
于 2013-08-20T00:53:01.657 に答える