формат даты в результате запроса linq
следующий запрос linq to entities дает результат ниже:
public class UserCountResult
{
public DateTime? date { get; set; } // **should this be string instead?**
public int users { get; set; }
public int visits { get; set; }
}
public JsonResult getActiveUserCount2(string from = "", string to = "")
{
var query = from s in db.UserActions
group s by EntityFunctions.TruncateTime(s.Date) into g
select new UserCountResult
{
date = g.Key, // can't use .toString("dd.MM.yyyy") here
users = g.Select(x => x.User).Distinct().Count(),
visits = g.Where(x => x.Category == "online").Select(x => x.Category).Count()
};
return Json(query, JsonRequestBehavior.AllowGet);
}
результат:
[{"date":"/Date(1383433200000)/","users":21,"visits":47},{"date":"/Date(1383519600000)/","users":91,"visits":236}]
вместо чего-то вроде /Date(1383433200000)/, мне нужна дата в формате " dd.Мм гггг", например
[{"date":"29.11.2013","users":21,"visits":47},{"date":"30.11.2013","users":91,"visits":236}]
Я не нашел способ, как изменить формат в запросе, и я не знаю, что делать.. Я даже не понимаю, почему г. Ключ является nullable .. Спасибо за любой вклад!
3 ответов
g.Key
является недействительным, потому что это подпись EntityFunctions.TruncateTime
. http://msdn.microsoft.com/en-us/library/dd395596.aspx.
чтобы выйти из Linq to Entities, вы можете оставить запрос как есть и проецировать его после факта:
return Json(query.AsEnumerable().Select(r => new
{
date = r.date.GetValueOrDefault().ToString("dd.MM.yyyy"),
users = r.users,
visits = r.visits
}), JsonRequestBehavior.AllowGet);
это не очень красиво, но это Linq для сущностей для вас.
предполагая, что вы используете JSON.NET в качестве сериализатора JSON вы можете применить JsonConverterAttribute
до date
свойство для указания пользовательского преобразователя.
[JsonConverter(typeof(MyDateConverter))]
public DateTime? date { get; set; }
можно использовать DateTimeConverterBase
class как базовый класс для вашего конвертера.
вот возможная реализация MyDateConverter
:
class CustomDateTimeConverter : DateTimeConverterBase
{
private const string Format = "dd.MM.yyyy";
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
DateTime d = (DateTime)value;
string s = d.ToString(Format);
writer.WriteValue(s);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (s == null)
return null;
string s = (string)reader.Value;
return DateTime.ParseExact(s, Format, null);
}
}
другой вариант-исключить date
свойство из сериализации (с помощью JsonIgnoreAttribute
), и добавить другое свойство типа String
, который преобразует их в нужный формат. Вот реализация этого решения:
public class UserCountResult
{
[JsonIgnore]
public DateTime? date { get; set; }
[JsonProperty("date")]
public string DateAsString
{
get
{
return date != null ? date.Value.ToString("dd.MM.yyyy") : null;
}
set
{
date = string.IsNullOrEmpty(value) ? default(DateTime?) : DateTime.ParseExact(value, "dd.MM.yyyy", null);
}
}
public int users { get; set; }
public int visits { get; set; }
}
что-то вроде этого должно работать:
date = new Date(parseInt(g.Key.substr(6)));
на substr
вытащит строку" /Date (",parseInt
вытащит только целое число, и дата даст вам новый объект даты.
EDIT:
просто нашел этот вопрос, который поддерживает этот ответ.