Преобразование даты и времени в отформатированную строку внутри запроса LINQ to SQL

Я знаю, что LINQ to SQL не конвертирует DateTime в string, поскольку в SQL нет ToString(). Но как преобразовать DateTime в форматированную строку?

Это строка в следующем запросе, который нуждается в помощи:

StartDate = string.Format("{0:dd.MM.yy}", p.StartDate)

Весь запрос:

var offer = (from p in dc.CustomerOffer
             join q in dc.OffersInBranch
             on p.ID equals q.OfferID
             where q.BranchID == singleLoc.LocationID
             let value = (p.OriginalPrice - p.NewPrice) * 100 / p.OriginalPrice
             orderby value descending
             select new Offer()
             {
                 Title = p.OfferTitle,
                 Description = p.Description,
                 BestOffer = value,
                 ID = p.ID,
                 LocationID = q.BranchID,
                 LocationName = q.CustomerBranch.BranchName,
                 OriginalPrice = SqlFunctions.StringConvert((decimal)p.OriginalPrice),
                 NewPrice = SqlFunctions.StringConvert((decimal)p.NewPrice),
                 StartDate = string.Format("{0:dd.MM.yy}", p.StartDate)
             }).First();

Появляется следующее сообщение об ошибке:

LINQ to Entities does not recognize the method 'System.String ToString(System.String)' method, and this method cannot be translated into a store expression.

Ответ 1

EDIT: теперь, когда я понимаю вопрос, я даю ему еще один снимок:)

var offer = (from p in dc.CustomerOffer
                     join q in dc.OffersInBranch
                         on p.ID equals q.OfferID
                     where q.BranchID == singleLoc.LocationID
                     let value = (p.OriginalPrice - p.NewPrice) * 100 / p.OriginalPrice
                     orderby value descending
                     select new
                     {
                         Title = p.OfferTitle,
                         Description = p.Description,
                         BestOffer=value,
                         ID=p.ID,
                         LocationID=q.BranchID,
                         LocationName=q.CustomerBranch.BranchName,
                         OriginalPrice=SqlFunctions.StringConvert((decimal)p.OriginalPrice),
                         NewPrice=SqlFunctions.StringConvert((decimal)p.NewPrice),
                         StartDate=p.StartDate

                     })
                     .ToList()
                     .Select(x => new Offer()
                     {
                         Title = x.OfferTitle,
                         Description = x.Description,
                         BestOffer=value,
                         ID=x.ID,
                         LocationID=x.BranchID,
                         LocationName=x.CustomerBranch.BranchName,
                         OriginalPrice=x.OriginalPrice,
                         NewPrice=x.NewPrice,
                         StartDate=x.StartDate.ToString("dd.MM.yy")
                     }).First();

Я знаю это немного долго, но проблема с Linq To SQL.

Когда вы используете linq, вызов базы данных не выполняется, пока вы не используете что-то вроде ToList() или First(), которое приводит к действительным объектам. Когда этот вызов SQL выполняется первым вызовом .First(), вы теперь работаете с типами .NET и можете использовать материал DateTime.

Ответ 2

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

var offer = (from p in dc.CustomerOffer
                 join q in dc.OffersInBranch
                     on p.ID equals q.OfferID
                 where q.BranchID == singleLoc.LocationID
                 let value = (p.OriginalPrice - p.NewPrice) * 100 / p.OriginalPrice
                 orderby value descending
                 select new
                 {
                     Title = p.OfferTitle,
                     Description = p.Description,
                     BestOffer=value,
                     ID=p.ID,
                     LocationID=q.BranchID,
                     LocationName=q.CustomerBranch.BranchName,
                     OriginalPrice=SqlFunctions.StringConvert((decimal)p.OriginalPrice),
                     NewPrice=SqlFunctions.StringConvert((decimal)p.NewPrice),
                     StartDate= SqlFunctions.DateName("day",p.StartDate) + "/" + SqlFunctions.DateName("month",p.StartDate) + "/" +  SqlFunctions.DateName("year",p.StartDate)

                 })

Мне было удобно, если вы не хотите добавлять дополнительный выделенный новый блок.

Ответ 3

если вам нужно использовать datetime .ToShortDateString(). Но вам также нужно объявить его AsEnumerable().

var offer = (from p in dc.CustomerOffer.AsEnumerable()
                 join q in dc.OffersInBranch
                     on p.ID equals q.OfferID
                 where q.BranchID == singleLoc.LocationID
                 let value = (p.OriginalPrice - p.NewPrice) * 100 / p.OriginalPrice
                 orderby value descending
                 select new
                 {
                     Title = p.OfferTitle,
                     Description = p.Description,
                     BestOffer=value,
                     ID=p.ID,
                     LocationID=q.BranchID,
                     LocationName=q.CustomerBranch.BranchName,
                     OriginalPrice=SqlFunctions.StringConvert((decimal)p.OriginalPrice),
                     NewPrice=SqlFunctions.StringConvert((decimal)p.NewPrice),
                     StartDate=p.StartDate

                 })
                 .ToList()
                 .Select(x => new Offer()
                 {
                     Title = x.OfferTitle,
                     Description = x.Description,
                     BestOffer=value,
                     ID=x.ID,
                     LocationID=x.BranchID,
                     LocationName=x.CustomerBranch.BranchName,
                     OriginalPrice=x.OriginalPrice,
                     NewPrice=x.NewPrice,
                     StartDate=x.StartDate.ToShortDateString()
                 }).First();

Ответ 4

Это то, что мы сделали, мы добавили новую функцию в класс, и мы запросим дату как обычно в запросе:

[ComplexType]
public class Offer
{    
    public DateTime StartDate 
    {
        get;
        set;
    }

   public String Title
   {
       get;
       set;
   }

   /*Other fields*/      
   .
   .
   .


    public string FormattedDate(string format)
    {
        return Date.ToString(format);
    }
}



var offer = (from p in dc.CustomerOffer
         join q in dc.OffersInBranch
         on p.ID equals q.OfferID
         where q.BranchID == singleLoc.LocationID
         let value = (p.OriginalPrice - p.NewPrice) * 100 / p.OriginalPrice
         orderby value descending
         select new Offer()
         {
             Title = p.OfferTitle,
             Description = p.Description,
             BestOffer = value,
             ID = p.ID,
             LocationID = q.BranchID,
             LocationName = q.CustomerBranch.BranchName,
             OriginalPrice = SqlFunctions.StringConvert((decimal)p.OriginalPrice),
             NewPrice = SqlFunctions.StringConvert((decimal)p.NewPrice),
             StartDate = p.StartDate
         }).First();

Затем вы можете просто вызвать поле FormattedDate, передав требуемый формат.

edit1.Text = offer.FormattedDate("dd.MM.yy");

Или может определить его как поле с только получателем:

    public string FormattedDate
                {
                   get { return Date.ToString("dd.MM.yy") };
                }

 edit1.Text = offer.FormattedDate;

Если вы являетесь классом Entity, вам нужно объявить новую часть этого класса и добавить поле.

Надеюсь, что это поможет кому-то.