Lambda表达式中DateTime格式转换问题求助
解决DateTime字段JSON序列化格式问题
我来帮你搞定这个日期格式的问题,你遇到的核心问题其实有两个:一是Linq to SQL不支持在查询中直接调用ToString()(因为SQL Server没法解析这个方法);二是你的DTO里date_joined是DateTime类型,试图把格式化后的字符串赋值给它会导致类型不匹配错误。下面给你几个可行的解决方案:
方案一:修改DTO字段类型为string(直接直观)
首先把你的DTO里的日期字段改成字符串类型:
public string date_joined { get; set; } public string date_of_birth { get; set; } // 同理,BirthDate如果是可空DateTime,也改成string
然后调整Linq查询,先把数据从数据库拉到内存(脱离Linq to SQL上下文),再做格式化:
var customer = db.PrmCustomers .Where(x => x.EmailAddress != null && x.CustomerID > id) .OrderBy(x => x.CustomerID) // 先匿名类获取原始数据,只拉取需要的字段,减少数据传输 .Select(x => new { x.EmailAddress, x.MobilePhoneNumber, x.Name, x.Surname, x.GenderType, x.CustomerID, x.CreateDate, x.BirthDate, x.Password, x.IsNewsletter, x.IsSms, x.IsApprovedEmail }) .AsEnumerable() // 关键:切换到Linq to Objects,此时可以安全调用ToString .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("dd.MM.yyyy HH:mm:ss"), // 正常格式化 last_login = "", date_of_birth = x.BirthDate.HasValue ? x.BirthDate.Value.ToString("dd.MM.yyyy") : "", password = x.Password, email_allowed = x.IsNewsletter, sms_allowed = x.IsSms, verified = x.IsApprovedEmail, social_account_facebook_uuid = "", social_account_facebook_extra = "" });
这样处理后,返回的JSON里就会是你想要的日期字符串格式了。
方案二:保持DTO类型不变,配置JSON序列化格式(推荐)
如果你不想修改DTO的结构,更推荐这种方式——直接配置JSON序列化器,让它自动把DateTime转成你要的格式,替代默认的/Date(xxx)/格式。
全局配置(所有JSON返回都生效)
在Global.asax.cs的Application_Start方法里添加以下配置(需要引用Newtonsoft.Json):
using Newtonsoft.Json; using Newtonsoft.Json.Converters; protected void Application_Start() { // 其他初始化代码... JsonConvert.DefaultSettings = () => new JsonSerializerSettings { DateFormatString = "dd.MM.yyyy HH:mm:ss", Converters = new List<JsonConverter> { new IsoDateTimeConverter { DateTimeFormat = "dd.MM.yyyy HH:mm:ss" } } }; }
配置后,所有返回的JSON里的DateTime都会自动转成指定格式,你的原有Linq查询完全不需要改动。
局部配置(仅当前Action生效)
如果只想在这个Action里单独设置,可以这样返回:
var jsonSettings = new JsonSerializerSettings { DateFormatString = "dd.MM.yyyy HH:mm:ss" }; var serializedCustomer = JsonConvert.SerializeObject(customer, jsonSettings); return Json(serializedCustomer, JsonRequestBehavior.AllowGet);
方案三:在SQL层面格式化(适合大数据量场景)
如果数据量很大,不想把所有数据拉到内存处理,可以用EF提供的SQL函数在数据库层面生成格式化后的字符串(同样需要DTO字段是string类型):
// EF6及之前用SqlFunctions,需要引用System.Data.Entity.SqlServer .Select(x => new CustomerDTO() { // 其他字段... date_joined = SqlFunctions.DateName("day", x.CreateDate) + "." + SqlFunctions.DateName("month", x.CreateDate) + "." + SqlFunctions.DateName("year", x.CreateDate) + " " + SqlFunctions.DateName("hour", x.CreateDate) + ":" + SqlFunctions.DateName("minute", x.CreateDate) + ":" + SqlFunctions.DateName("second", x.CreateDate), // 其他字段... })
如果是EF Core,就用EF.Functions.DatePart来替代,不过这种写法比较繁琐,一般不推荐,除非有性能上的特殊需求。
内容的提问来源于stack exchange,提问作者Ege Bayrak
相关产品推荐
相关产品推荐

