2015-08-05 6 views
1

Не могли бы вы рассказать мне, как исправить запрос ниже. LINQ формировал мои даты как выписанный пример: 8 августа 2015 года. Мне нужно 8/8/2015. Каждая попытка, которую я пытаюсь, дает мне другое сообщение об ошибке. Что я делаю не так.Linq Can not Перевести ToShortDateString()

var orgData = (from d in db.tbl_FormsSubmittedValues 
       where d.SiteID == _siteID 
       & d.FormID == _formID 
       & ((d.tbl_FormsSubmitted.UserID == _userID && _viewOwnOnly) || !_viewOwnOnly) 
       & ((_search != "" && d.Value.Contains(_search)) || _search == "") 
       select new 
       { 
        d.FormSubmissionID, 
        Value = d.ValueDate.HasValue ? d.ValueDate.Value.ToShortDateString(): d.ValueLong != null ? d.ValueLong : d.Value, 
        d.FieldID, 
        d.FormID, 
        d.SiteID, 
        d.tbl_FormsSubmitted, 
        d.tbl_FormsSubmitted.UserID, 
       }).ToList(); 

Оригинальная линия Это дает мне выписал дату вместо мм/дд/гггг

Value = d.ValueDate != null ? d.ValueDate.ToString() : d.ValueLong != null ? d.ValueLong : d.Value, 

Проблема Линия:

Value = d.ValueDate.HasValue ? d.ValueDate.Value.ToShortDateString(): d.ValueLong != null ? d.ValueLong : d.Value, 

Ошибка:

Could not translate expression 'd.ValueDate.Value.ToShortDateString()' into SQL and could not treat it as a local expression. 

ответ

1

Я рекомендую:

Value = d.ValueDate.HasValue ? (d.ValueDate.Value.Day + "/" + d.ValueDate.Value.Month + "/" + d.ValueDate.Value.Year) : (d.ValueLong != null ? d.ValueLong : d.Value), 

Или делать toshortstring при отображении данных (если вы используете его на сайте)

Или даже разобрать дату через JavaScript, используя разобранную дату (JSON)

1

Do форматирование за пределами реального sql. Что-то вроде:

orgData = (from d in db.tbl_FormsSubmittedValues 
      where d.SiteID == _siteID 
      & d.FormID == _formID 
      & ((d.tbl_FormsSubmitted.UserID == _userID && _viewOwnOnly) || !_viewOwnOnly) 
      & ((_search != "" && d.Value.Contains(_search)) || _search == "") 
      select new { 
         d.FormSubmissionID, 
         Value = d.ValueDate.HasValue ? d.ValueDate.Value: d.ValueLong != null ? d.ValueLong : d.Value, 
         d.FieldID, 
         d.FormID, 
         d.SiteID, 
         d.tbl_FormsSubmitted, 
         d.tbl_FormsSubmitted.UserID 
         }).AsEnumerable() //Using this to get the query to run. 
      //Anything after this should not be done on the database side. 
      .Select(d => new 
      { 
       d.FormSubmissionID, 
       Value = d.ValueDate.HasValue ? FormatDate(d.ValueDate.Value): d.ValueLong != null ? d.ValueLong : d.Value, 
       d.FieldID, 
       d.FormID, 
       d.SiteID, 
       d.tbl_FormsSubmitted, 
       d.tbl_FormsSubmitted.UserID, 
      }).ToList(); 


static string FormatDate(DateTime date) 
{ 
    return date.Value.ToShortDateString(); 
} 

Это позволяет отформатировать исходный код sql.

+0

Возможно, вам захочется выделить то, что вы на самом деле сделали, чтобы форматирование произошло за пределами sql. Я почти пропустил это, и я искал его! :) – Chris

+0

@Chris достаточно справедливо :) теперь редактирование – psoshmo

+0

Я бы этого не сделал, потому что даже если вы выполняете предложение where, вы выталкиваете все столбцы из db.tbl_FormsSubmittedValues. Я бы выбрал вариант, дружественный к производительности. –

2

Альтернативой созданию нового анонимного объекта было бы создание нового типизированного объекта (например, select new Submission() { ... }), который предоставляет свойство только для чтения для рендеринга короткой даты. Это может добавить некоторые накладные расходы для такой простой операции, но она предлагает некоторую гибкость (вы можете форматировать больше полей позже) и производительность (любые дополнительные операции запроса или фильтра выполняются вместо базы данных, а не в памяти).

Или вы можете нажать на трубу вниз на слой презентации. Пусть код, ответственный за отображение данных для обработки пользовательского дескриптора, преобразование или отображение короткой даты и сохранение ваших данных/бизнес-слоев, ориентированы на другие интерпретации. Это не позволит вам вернуться и изменить запрос или изменить свой POCO, чтобы учесть изменение предпочтения формата даты. Например, что, если бы у вас был другой человек, который предпочел бы, чтобы дата была показана как YYYY-dd-MM?

+0

Прошу прощения, я в замешательстве. Я должен создать класс, используя те же свойства, которые я могу объявить в текущем запросе. Замените оператор 'new' новым классом. В этот момент запрос будет выполняться по-разному? – jackncoke

+0

Нет нет. Я подчеркиваю потенциальную проблему, основанную на ответе @ psoshmo. Существуют соображения производительности, основанные на том, как вы пишете свои запросы. Когда вы запрашиваете «AsEnumerable» или «ToList», вы сигнализируете инфраструктуре о выполнении запроса в базе данных. Если вы хотите добавить предложение Where после одного из них, вы будете фильтровать данные в памяти, а не в базе данных. Это потенциально очень дорого. Это то, что я имел в виду под «любыми дополнительными операциями запроса или фильтрации». Создание свойства только для чтения избавляет вас от выбора всех данных в памяти для выполнения фильтра. – villecoder