jqGrid & ASP.NET 4 MVC: Как реализовать поиск в репозитории DBContext и «вычисляемых» свойствах? - PullRequest
0 голосов
/ 27 января 2012

Я пытаюсь реализовать поиск jqgrid в MVC, следуя интересному ответу @Oleg относительно вопроса: ASP.NET MVC 2.0 Реализация поиска в jqgrid .

На самом делеУ меня есть хранилище данных на основе EF & DBContext.Более того, у меня есть сущность с «вычисляемыми» полями, я имею в виду свойства в DbSets, которые рассчитываются на основе других полей.

У меня есть две основные проблемы, реализующие решение, описанное в первом ответе вышессылка:

1-я проблема) Решение основано на ObjectQuery.Я полагаю, что я решил, создав IObjectContextAdapter своего контекста и затем применив (ObjectQuery) ... в моем незнании, я точно не знаю, может ли это решение рассматриваться как масштабируемое или есть лучшее решение ... Iя уверен, что он существует, но он мне не известен!

2-я проблема) При первом запросе возникает следующее исключение EntitySqlException: 'Calculated' не является членом типа 'Models.Ticket' в загруженных в настоящее время схемах

Можете ли вы дать мне какую-то помощь или предложение по вышеуказанным проблемам, пожалуйста?

Здесь я поместил некоторые части кода, которые, я думаю, могли бы прояснить:

ОБЩЕСТВЕННАЯENUM общедоступный enum StatiTT: int {A = 1, B = 2, C = 3, D = 4, E = 5, F = 6, G = 7};

'TICKET'ENTITY

 public class Ticket : IValidatableObject
 {

  public DateTime Data1 { get; set; }    
  public int StatoTicketID { get; set; }
....
  public int Calculated  // here's the problem...this is not a real field, it's a calculated property, as you see...
   {
      get
       {
           int mm=0;

           DateTime Ora = DateTime.Now;

           mm = (Data1 - Ora).Days*1440 + (Data1 - Ora).Hours * 60 + (Data1 - Ora).Minutes;

           if (StatoTicketID > (int)StatiTT.DI && mm < 0) mm = 10000000; 

           return mm;
       }
   }

КОНТЕКСТ

public class dbContext : DbContext
   {

       public DbSet<Ticket> Tickets{ get; set; }
     ........

** Хранилище (фактически не используется в вышеуказанном решении) **

public class myRepository : ImyRepository, IDisposable
{
    private dbContext context;

    public myRepository(dbContext context)
    {
        this.context = context;
    }

    public IQueryable<Ticket> ListTicketsQ()
    {
        return (from e in context.Tickets select e);
    }
    ..........

КОНТРОЛЛЕР

     public JsonResult jqIndex(string sidx, string sord, int page, int rows, bool _search, string filters)
    {
        var context = new dbContext();
        var objectContext = ((IObjectContextAdapter)context).ObjectContext;
        var set = objectContext.CreateObjectSet<Ticket>();

        var serializer = new JavaScriptSerializer();
        Filters f = (!_search || string.IsNullOrEmpty(filters)) ? null : serializer.Deserialize<Filters>(filters);
        ObjectQuery<Ticket> filteredQuery =
            (f == null ? (ObjectQuery<Ticket>)set : f.FilterObjectSet((ObjectQuery<Ticket>)set));
        filteredQuery.MergeOption = MergeOption.NoTracking; // we don't want to update the data
        var totalRecords = filteredQuery.Count();

        var pagedQuery = filteredQuery.Skip("it." + sidx + " " + sord, "@skip",
                                            new ObjectParameter("skip", (page - 1) * rows))
                                     .Top("@limit", new ObjectParameter("limit", rows));
        // to be able to use ToString() below which is NOT exist in the LINQ to Entity
        var queryDetails = (from item in pagedQuery
                            select new {     
                                            item.Calculated, // << THIS 'property' RAISES EntitySqlException
                                            }).ToList();
         .....

Любая помощь будет оценена.Большое спасибо!

Ответы [ 2 ]

1 голос
/ 30 января 2012

Мне кажется, у вас есть какие-то проблемы с Entity Framework.Я думаю, что вы можете решить эту проблему, перенеся вычисление свойства Ticket.Calculated непосредственно в следующий оператор

var queryDetails = (from item in pagedQuery
                    select new {
                        ...
                        (item.Amount + item.Tax), // Calculated directly
                        ...
                    }).ToList();

В случае, если при вычислении свойства не будет использоваться Entity SQL и поэтому у вас не будет EntitySqlException исключения.Такой подход должен работать.При необходимости вы можете инкапсулировать вычисление свойства в любую функцию.

Другим способом может быть использование вычисления дополнительного свойства непосредственно в коде JavaScript на стороне клиента .Например, если вам нужно отобразить зависимые от дерева столбцы в сетке: сумма, налог и общая сумма, которая является просто суммой суммы и налога, вы можете сделать это на стороне клиента в коде JavaScript.jqGrid имеет функцию обратного вызова beforeProcessing, которая будет вызываться до обработки сообщения data, возвращаемого с сервера.Таким образом, Вы можете перечислять элементы в data.rows и устанавливать свойство total каждого элемента как сумму amount и tax (преобразованную из String в Number).Таким образом вы уменьшите размер данных, которые будут передаваться между сервером и клиентом.

0 голосов
/ 14 февраля 2012

Лучшее рабочее решение моей проблемы было решено после ценных подсказок г-на @Oleg: Я переместил вычисленные свойства в SQL Server, создав Computed Columns для каждого свойства . Теперь все работает отлично и очень быстро!

Я потерял больше времени, пытаясь настроить вычисляемые свойства с помощью ObjectSet, чем создавать новые вычисляемые столбцы прямо в БД! Как правильно заметил Олег, простые вещи всегда самые лучшие!

Еще один совет для тех, кто использует EF Codefirst: если вы хотите использовать вычисляемые свойства, вы должны DROP COLUMNS после создания db и поставить атрибут [DatabaseGenerated(DatabaseGeneratedOption.Computed)] над свойством, как указано в здесь 1011 *

Большое спасибо, Олег ! Я надеюсь, что это решение может помочь другим людям!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...