LINQ to SQL большой кортеж запросов - PullRequest
3 голосов
/ 14 марта 2012

Я не спланировал проект правильно с самого начала, поэтому у меня появилось много SQL-запросов, разбросанных по странице.

Поэтому, чтобы не перехватывать исключения Sql во всех других методах или пропустить половину страницы из-за исключения в одномметодов, которые я хочу получить все данные, которые мне нужны, так:

Это метод из файла DLL, мне нужно вернуть его, чтобы я мог работать с объектами после удаления контекста, но я делаю что-то ужасно неправильно (первый запросfinalproduct возвращается пустым):

 public static Tuple<Product, IEnumerable<Tag>, IEnumerable<ProductComment>, IEnumerable<ProductVote>, IEnumerable<Review>, IEnumerable<ReviewComment>, IEnumerable<ReviewVote>> GetBigProduct(int productID)    
            {
                using (ProductClassesDataContext context = new ProductClassesDataContext())
                {
                    var outproduct = from product in context.Products
                                     where product.ID == productID
                                     join producttag in context.ProductTags on product.ID equals producttag.productID
                                     join tag in context.Tags on producttag.TagID equals tag.ID
                                     join productComment in context.ProductComments on product.ID equals productComment.productID
                                     join productVote in context.ProductVotes on product.ID equals productVote.productID
                                     join review in context.Reviews on product.ID equals review.productID
                                     join reviewComment in context.ReviewComments on review.ID equals reviewComment.reviewID
                                     join reviewVote in context.ReviewVotes on review.ID equals reviewVote.reviewID
                                     select new Tuple<Product, Tag, ProductComment, ProductVote, Review, ReviewComment, ReviewVote>
                                                     (product, tag, productComment, productVote, review, reviewComment, reviewVote);


                    var finalProduct = (from t in outproduct select t.Item1).Single();

                    var finalTags = (from t in outproduct select t.Item2).ToList();

                    var finalProductComments = (from t in outproduct select t.Item3).ToList();

                    var finalProductVotes = (from t in outproduct select t.Item4).ToList();

                    var finalReviews = (from t in outproduct select t.Item5).ToList();

                    var finalReviewsComments = (from t in outproduct select t.Item6).ToList();

                    var finalReviewsVotes = (from t in outproduct select t.Item7).ToList();

                    return new Tuple<Product, IEnumerable<Tag>, IEnumerable<ProductComment>, IEnumerable<ProductVote>, IEnumerable<Review>, IEnumerable<ReviewComment>, IEnumerable<ReviewVote>>
                               (finalProduct, finalTags, finalProductComments, finalProductVotes, finalReviews, finalReviewsComments, finalReviewsVotes);
                }
            }

Ответы [ 3 ]

2 голосов
/ 14 марта 2012

Вы уверены, что запрос from t in outproduct select t.Item1 возвращает только один элемент? Согласно документации , Single():

Возвращает единственный элемент последовательности и выдает исключение, если в последовательности нет ни одного элемента.

Вам может понадобиться First() или FirstOrDefault().

Обновление после комментариев

Я думаю, проблема в твоих соединениях. На самом деле, я не думаю, что вы хотите присоединиться здесь. Я думаю, вам нужно что-то вроде следующего:

var outproduct = from product in context.Products
                 where product.ID == productID
                 select new Tuple<Product, ProductComment, Tag>(
                      product, // product itself
                      context.ProductComments.Where(p => p.productID == product.ID).ToList(), // list of comments for this product
                      (from pt in context.ProductTags
                      join tag in context.Tags on pt.TagID equals tag.ID
                      where pt.productID = product.ID
                      select tag).ToList() // list of tags for this product
                      // ... more dimensions in tuple
                 );

Затем из запроса outproduct вы получите набор кортежей, содержащий <Product, List of ProductComments, List of Tags>. Вы можете легко добавить остальные размеры вашего кортежа. Я удалил их для простоты.

Теперь вы можете вернуть этот кортеж непосредственно из вашей функции, выполнив всего лишь

return outproduct.FirstOfDefault()

Нет необходимости в линиях в стиле var finalProduct = и перестройке финального кортежа.

1 голос
/ 14 марта 2012

Если вы хотите найти источник проблемы,

начать с запроса без каких-либо объединений, закомментировать строки результатов, кроме первой строки

   var outproduct = from product in context.Products
          where product.ID == productID
          select new Tuple<Product>(product);

, если это даст вам некоторые результаты, добавьте следующее соединение и попробуйте снова. продолжайте добавлять объединения по одному, пока ваш запрос не будет выполнен. тогда вы должны иметь и понять, где проблема.

0 голосов
/ 14 марта 2012

Если вы используете FirstOrDefault () вместо Single (), это не будет возвращать ноль.

Надеюсь, это поможет.

...