Используя LINQ в моем Business Logi c, но получаю ошибку - PullRequest
0 голосов
/ 28 апреля 2020

Идея состоит в том, что ссылочный номер или поставщик может быть передан в лог c, и он возвращает результаты запроса для поиска. Я знаю, что что-то упускаю .. Просто не вижу этого ..

Идея запроса SQL была следующей:

 "SELECT ReferenceNumber, VendorName, RequisitionStatus, RequestedOn, sum(RequisitionQTY*RequisitionPrice) as Total FROM partrequisition where ReferenceNumber = 105543 Group By 'ReferenceNumber' "

Кто-нибудь может помочь?

Я получаю следующую ошибку:

CS0029 Не удается неявно преобразовать тип System.Collections.Generic.List<decimal?> в System.Data.Entity.DbSet<PartsManagement.Models.partrequisition>

(contoller)
public ActionResult Index(RequisitionSearch searchModel)
{
      var PartRequisitionInfoLogic = new PartRequisitionInfoLogic(); //This is where any business Logic goes
      var Model = PartRequisitionInfoLogic.Getpartrequisitions(searchModel); //This is where it figures out what Search Query is
      var RequisisionResults = Model.ToList();
}
(Business Logic)
private wsdpartsmanagementEntities9 db = new wsdpartsmanagementEntities9();

public IQueryable<partrequisition> Getpartrequisitions(RequisitionSearch searchModel)
{

    var result = db.partrequisitions.AsQueryable();

    if (searchModel != null)
    {

        if (searchModel.ReferenceNumber != 0 && searchModel.VendorID == 0)

            result = result.Where(c => c.ReferenceNumber == searchModel.ReferenceNumber).GroupBy(c => c.ReferenceNumber)
                        .Select(g => g.Sum(item => item.RequisitionQTY * item.RequisitionPrice)) // For each group, calculate the sum
                        .ToList();

            if (searchModel.ReferenceNumber == 0 && searchModel.VendorID != 0)

                result = result.Where(c => c.VendorName == searchModel.VendorID).GroupBy(c => c.ReferenceNumber)
                        .Select(g => g.Sum(item => item.RequisitionQTY * item.RequisitionPrice))// For each group, calculate the sum
                        .ToList();
        }


        return result;
}
(ViewModel(s))
    public class RequisitionSearch
    {
        public int? VendorID { get; set; }
        public int? ReferenceNumber { get; set; }
        public List<RequisitionResults> SearchResults { get; set; }

        public RequisitionSearch()
        {
            this.SearchResults = new List<RequisitionResults>();
        }
    }
}

public class RequisitionResults
    {
        public int ReferenceID { get; set; }
        [Display(Name = "Reference Number")]
        public int ReferenceNumber { get; set; }
        [Display(Name = "Vendor Name")]
        public string VendorName { get; set; }
        [Display(Name = "Requisition Status")]
        public string RequisitionStatus { get; set; }
        [Display(Name = "Requisition On")]
        public DateTime RequestedOn { get; set; }
        [DisplayFormat(DataFormatString = "{0:C}")]
        [Display(Name = "Requisition Total")]
        public decimal RequisitionTotal { get; set; }

    }

Обновление .. Решением было удалить бизнес-логику c и заменить ее (ниже) в ActionResult. Работает отлично.

var result = db.partrequisitions.AsQueryable();
if (searchModel.ReferenceNumber != null || searchModel.VendorID != null)
 {
   result = result.Where(partrequisition => partrequisition.ReferenceNumber == searchModel.ReferenceNumber || partrequisition.VendorName == searchModel.VendorID);
 }
 else
 {
    result = result.Distinct();
 }            

 var b = result.GroupBy(x => x.ReferenceNumber);
 var c = b.Select(group => group.Sum(partRequistion => partRequistion.RequisitionQTY * partRequistion.RequisitionPrice));

И для доступа к информации о запросе пара циклов foreach ..

Ответы [ 2 ]

1 голос
/ 28 апреля 2020

Внимательно посмотрите на следующую строку:

 result = result.Where(c => c.VendorName == searchModel.VendorID)
                .GroupBy(c => c.ReferenceNumber)
                .Select(g => g.Sum(item => item.RequisitionQTY * item.RequisitionPrice))// For each group, calculate the sum
                .ToList();

Вы пытаетесь вернуть значения List из Decimal?, используя метод Sum, тогда как тип возврата вашего метода равен IQueryable<partrequisition> , Так что вам нужно либо изменить тип возвращаемого вами метода на List из Decimals?, либо изменить свой запрос, чтобы выполнить то, что на самом деле нужно вашему методу, вернув IQueryable из partrequisition.

0 голосов
/ 28 апреля 2020

Если бы вы разбили большой запрос на более мелкие и использовали ключевое слово var гораздо реже, то вы бы увидели свою проблему во время компиляции:

Увы, вы забыли описать свой класс PartRequisition , Из вашего кода это выглядит примерно так:

class PartRequisition
{
    public int ReferenceId {get; set;}
    public int ReferenceNumber {get; set;}

    public decimal? RequisitionQty {get; set;}
    public decimal? RequisitionPrice {get; set;}
    // one of them might be not a decimal? but a decimal.
}

Ваш код:

IQueryable<PartRequisition> result = db.partrequisitions.AsQueryable();
result = result
    .Where(partRequistion => partRequisition.ReferenceID == searchModel.ReferenceNumber)
    .GroupBy(partRequistion => partRequistion.ReferenceNumber)
    .Select(group => group.Sum(partRequistion =>
            partRequistion.RequisitionQTY * partRequistion.RequisitionPrice))
    .ToList();

Давайте разделим это на более мелкие части:

IQueryable<PartRequisition> result = ...
IQueryable<PartRequisition> a =  result.Where(partRequistion => ... == ...);
IQueryable<IGrouping<int, PartRequisition>> b = a.GroupBy(
                          partRequistion => partRequistion.ReferenceNumber);

Так что b является запрашиваемым последовательность групп. Каждая группа имеет целочисленное свойство Key. Каждая группа также представляет собой последовательность PartRequistions, а именно все PartRequisitions, которые имеют значение ReferenceNumber, равное ключу.

При выборе вы берете каждую группу из своей последовательности групп. Из каждого элемента в этой группе (который является PartRequisition) вы умножаете два свойства decimal?, что дает нам результат decimal?. После этого вы суммируете эти результаты, используя Sum<decimal?>

IQueryable<decimal?> c = b.Select(group => group.Sum(partRequistion =>
    partRequistion.RequisitionQTY * partRequistion.RequisitionPrice)

Или еще более мелкими шагами:

  • c is IQueryable> `
  • Каждая группа равно IGrouping<int, PartRequisition>
  • каждая частьRequisition - это PartRequisition
  • , каждый RequisitionQTY и RequisitionPrice являются десятичными?
  • результат умножения равен decimal?
  • сумма равна decimal?
  • d - IQueryable

Наконец:

List<decimal?> d = c.ToList();
result = d;  // remember, result is an IQueryable<PartRequisition>

Понятно, что вы не можете назначить от List<decimal?> до IQueryable<PartRequisition>, что и было ошибкой:

CS0029 Невозможно неявно преобразовать тип List в DbSet

Назад к вашему задача

Вы описали класс RequistionResult, который вы не использовали в методе GetRequisitions. Может ли быть так, что вы не хотите возвращать IQueryable<PartRequistions>, а IQueryable<RequisitionResult>, где свойство RequisitionTotal - это ваша расчетная сумма?

public IQueryable<RequisitionResult> GetRequisitions(...)
{
    IQueryable<PartRequisition> partRequisitions = db.partrequisitions.AsQueryable();

    if (searchModel != null)
    {
        if (searchModel.ReferenceNumber != 0 && searchModel.VendorID == 0)
        {
            partRequisitions = partRequisitions.Where(...);
        }
        else if (searchModel.ReferenceNumber == 0 && searchModel.VendorID != 0)
        {
            partRequisitions = partRequisitions.Where(...);
        }
        // else use all PartRequisitions
    }
    else
    {
         // TODO: decide what to return if searchModel is null, for example
         partRequisitions = IQueryable.Empty<PartRequisition>();
         // or use all PartRequisitions
    }

    // from the remaining set of PartRequisitions, convert to RequisitionResults:
    IQueryable<RequisitionResult> requisitionResults = partRequisitions
        .GroupBy(partRequisition => partRequisition.ReferenceNumber,

        // parameter ResultSelector: take each ReferenceNumber and all PartRequisitions
        // with this ReferenceNumber to make one new RequisitionResult
        (referenceNumber, partRequisitionsWithThisReferenceNumber) => new RequisitionResult
        {
            RequisitionTotal = partRequisitionsWithThisReferenceNumber
               .Select(partRequisition => partRequisition.RequisitionQty * partRequisition.RequisitionPrice)
               .Sum(),

            // fill other properties
            ...
        });
    return requisitionResults;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...