Changing DateTime format in lambda Expression

自闭症网瘾萝莉.ら 提交于 2021-02-10 16:02:37

问题


I have a DTO field in DateTime format

public DateTime date_joined { get; set; }

I use this to turn the data into a Json

public JsonResult Customer(int? id)
        {
            var user = User.Identity.Name;
            if (!AccountController.IsInRole(user, "admin"))
            {
                return null;
            }

            id = id == null ? 0 : id;

            var customer = db.PrmCustomers
                .Where(x => x.EmailAddress != null && x.CustomerID > id)
                .OrderBy(x => x.CustomerID)
                .Select(x => new CustomerDTO()
                {
                    email = x.EmailAddress,
                    phone = x.MobilePhoneNumber,
                    username = "",
                    first_name = x.Name,
                    last_name = x.Surname,
                    gender = x.GenderType,
                    customer_code = x.CustomerID,
                    is_active = "",
                    //date_joined = String.Format("{0:d/M/yyyy HH:mm:ss}", x.CreateDate.ToString()),
                    date_joined = x.CreateDate,
                    last_login = "",
                    date_of_birth = x.BirthDate,
                    //date_of_birth = String.Format("{0:d/M/yyyy HH:mm:ss}", x.BirthDate.ToString()),
                    password = x.Password,
                    email_allowed = x.IsNewsletter,
                    sms_allowed = x.IsSms,
                    verified = x.IsApprovedEmail,
                    social_account_facebook_uuid = "",
                    social_account_facebook_extra = ""
                });

            return Json(customer, JsonRequestBehavior.AllowGet);
        }

Problem is, it comes up as this

"date_joined":"\/Date(1516965473683)\/"

I tried to change it into another format so far I couldn't manage it.

First I tried the usual DateTime formatting as toString("newFOrmat") but I got Linq errors mostly because toString() is not recognized in SQL Server

Then I came across this question format date in linq query result and tried the method there as this

return Json(customer.AsEnumerable().Select(r=>new CustomerDTO{
                date_joined = r.date_joined.GetValueOrDefault().ToString("dd.MM.yyyy")
            }) , JsonRequestBehavior.AllowGet);

I got "DateTime does not have a definition for GetValueOf()" error although I have the correct namespaces included.

Omitting it and using only the usual ToString("format") brought the Linq error above.

Any other suggestions?

EDIT: My DTO and Output has other fields too. I didn't include them in the question.


回答1:


I think your best bet here is to load in the required data from the database by calling .ToList(), and then map that data to your DTO.
Make sure to change the type on your DTO from DateTime to string.

Something like this:

public JsonResult Customer(int? id)
    {
        var user = User.Identity.Name;
        if (!AccountController.IsInRole(user, "admin"))
        {
            return null;
        }

        id = id == null ? 0 : id;

        var customer = db.PrmCustomers
            .Where(x => x.EmailAddress != null && x.CustomerID > id)
            .OrderBy(x => x.CustomerID).ToList()  //  <-- ToList executes the query
            .Select(x => new CustomerDTO()
            {
                email = x.EmailAddress,
                phone = x.MobilePhoneNumber,
                username = "",
                first_name = x.Name,
                last_name = x.Surname,
                gender = x.GenderType,
                customer_code = x.CustomerID,
                is_active = "",
                date_joined = x.CreateDate.ToString("d/M/yyyy HH:mm:ss"),
                //date_joined = x.CreateDate,
                last_login = "",
                //date_of_birth = x.BirthDate,
                date_of_birth = x.BirthDate.ToString("d/M/yyyy HH:mm:ss"),
                password = x.Password,
                email_allowed = x.IsNewsletter,
                sms_allowed = x.IsSms,
                verified = x.IsApprovedEmail,
                social_account_facebook_uuid = "",
                social_account_facebook_extra = ""
            });

        return Json(customer, JsonRequestBehavior.AllowGet);
    }



回答2:


So you basically need to call a Database function to convert your date to a string.

There is an awesome Library to help with mapping Database functions and Stored Procedures to Entity Framework.

I changed the code below to more or less what you need from code that worked for me converting a string to int. so there might be small mistakes that slipped in for changing to a DateTime function.

You can maybe consider mapping the "Format" function of SQL, and then you will be able to pass the date format from linq, but in the example below, i assume you created a function in SQL named DATE_TO_STRING

Install the Nuget package

- Install-Package EntityFramework.Functions

Create Extension Methods for functions:

public static class SQLFunctions
{
   [Function(FunctionType.BuiltInFunction, "DATE_TO_STRING")]
   public static string SqlDateToString(this DateTime value) => Function.CallNotSupported<string>();
}

Map it on your EntityFramework Context:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
   modelBuilder.Conventions.Add(new FunctionConvention(typeof(SQLFunctions)));
}

Call your newly mapped "SqlDateToString()" function in your LINQ queries:

.Select(p => p.YourDateColumn.SqlDateToString());

and bobs your uncle.

Another option will be to use MomentJs instead, that can understand that json date format very well, and then you do not need this mapping stuff.




回答3:


I don't like the accepted answer; I suggest you to extend JsonResult (googling you can find many post that use this approach) and override the ExecuteResult method:

public class JsonNetResult : JsonResult
{
  public object Data { get; set; }

  public JsonNetResult()
  {
  }

  public override void ExecuteResult(ControllerContext context)
  {
     HttpResponseBase response = context.HttpContext.Response;
     response.ContentType = "application/json";
     if (ContentEncoding != null)
         response.ContentEncoding = ContentEncoding;
     if (Data != null)
     {
          JsonTextWriter writer = new JsonTextWriter(response.Output) { Formatting = Formatting.Indented };
          JsonSerializer serializer = JsonSerializer.Create(new JsonSerializerSettings());
          serializer.Serialize(writer, Data);
          writer.Flush();
     }
  }
}

and finally:

return new JsonNetResult() { Data = customer };

This code return dates in ISO Format



来源:https://stackoverflow.com/questions/48463478/changing-datetime-format-in-lambda-expression

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!