Публикация значения времени в базу данных Universe из .NET Entity Framework
У меня есть приложение C#, которое получает данные JSON и записывает модель обратно в Universe. В ряде моделей мне нужно разделить поля ДАТА и ВРЕМЯ и записать их по отдельности при создании модели.
NET Framework V4.6.1, пакет NuGet U2.Data V2.2.2, U2NDK V2.2.2, Universe V11.2.5
Я создал модель во Вселенной с помощью RocketU2:
@ID TYPE LOC CONV ... DATA TYPE
Id D 0 CHAR(30)
AdjustmentDate D 1 D4- DATE
AdjustmentTime D 2 MTS TIME
Моей первой реакцией было написать это в контроллере:
AdjustmentTime = DateTime.Now.TimeOfDay;
И это в моделях приложений C#:
public TimeSpan AdjustmentTime { get; set; }
Это привело к ошибке: "Нет типа хранилища, соответствующего типу EDM 'Edm.Time' примитивного типа 'Time'".
Возник ряд вопросов относительно того, как вести время отдельно в базу данных. Итак, я пробовал их, и вот результат:
ProductAdjustmentController:
[Route("")]
[HttpPost]
public HttpResponseMessage PostProductAdjustment([FromBody] ProductAdjustmentCreate productAdjustmentCreate)
{
ResponseCollectionMember _response = new ResponseCollectionMember();
try
{
var id = productAdjustmentCreate.ProductId + "*" + productAdjustmentCreate.AdjustmentDate.ToString() + "*" + productAdjustmentCreate.AdjustmentTime.ToString();
var productAdjustmentEntity = new ProductAdjustmentEntity()
{
Id = id,
AdjustmentDate = DateTime.Now.Date,
AdjustmentTime = DateTime.Now.TimeOfDay.Ticks,
};
_context.ProductAdjustments.Add(productAdjustmentEntity);
}
Модель ProductAdjustmentEntity:
public class ProductAdjustmentEntity : FileBase<string>
{
public string ProductId { get; set; }
public DateTime? AdjustmentDate { get; set; }
public long AdjustmentTime { get; set; }
[NotMapped]
public TimeSpan Time
{
get { return TimeSpan.FromTicks(AdjustmentTime); }
set { AdjustmentTime = value.Ticks; }
}
}
ProductAdjustment Создать модель:
public class ProductAdjustmentCreate
{
[Required]
public string ProductId { get; set; }
public DateTime? AdjustmentDate { get; set; }
public long AdjustmentTime { get; set; }
[NotMapped]
public TimeSpan Time
{
get { return TimeSpan.FromTicks(AdjustmentTime); }
set { AdjustmentTime = value.Ticks; }
}
}
Я получаю ту же ошибку неподдерживаемого примитивного типа для другого типа: "Нет типа хранилища, соответствующего типу EDM 'Edm.Int64' примитивного типа 'Int64'".
Я покопался в пакете U2.Data и обнаружил, что существуют U2.Data.ClientTypes.Int64 и Time. Последнее, что я пробовал, - это создать метод, который переводил бы мои значения создания модели в принятое для U2 значение:
public static U2Int64 ConvertToU2Int64(long time)
{
U2Int64 u2Time = time;
return u2Time;
}
Но все это возвращает null.
Я просто хочу, чтобы это сработало, чтобы я мог протестировать публикацию модели во Вселенной.
Мои вопросы по проработке этого процесса: есть ли простой способ сделать это? Как мне распознать примитивные типы? Как мне написать метод их преобразования, который я мог бы использовать во всем приложении?
2 ответа
У меня есть статический класс, который я использую для преобразования значений времени в структуру времени выбора, которая представляет собой просто количество секунд с полуночи. Когда вы вызываете TIME() в Universe, он возвращает двойное значение.
На самом деле сложнее всего определить, когда полночь зависит от того, с каким значением DateTime вы работаете. Вот почему у меня есть две разные версии для использования DateTime и DateTimeOffset.
У меня также есть третий метод, который их рекомбинирует.
public static class Time
{
public static double GetPickTimeFromDateTime(DateTime dt)
{
DateTime midnight = DateTime.Parse(dt.Date.ToString());
TimeSpan ts = dt - midnight;
return ts.TotalSeconds;
}
public static double GetPickTimeFromDateTimeOffset(DateTimeOffset dt)
{
DateTimeOffset midnight = DateTime.Parse(dt.Date.ToString());
TimeSpan ts = dt - midnight;
return ts.TotalSeconds;
}
public static DateTime GetDateTimeDateAndPickTime(DateTime date, double pickTime)
{
return date.AddSeconds(pickTime);
}
}
Обычно вы пытаетесь найти тип данных для столбца (ну, в терминах РСУБД), который хорошо сочетается с типом данных dotnet.
Вот MySql .. КАК ПРИМЕР.. такого сопоставления.
https://www.devart.com/dotconnect/mysql/docs/DataTypeMapping.html
После того, как вы найдете волшебный тип данных... вы должны указать EF использовать его (вместо того, чтобы полагаться на значения по умолчанию)
public class Blog
{
public int BlogId { get; set; }
[Column(TypeName = "varchar(200)")]
public string Url { get; set; }
[Column(TypeName = "decimal(5, 2)")]
public decimal Rating { get; set; }
}
в приведенном выше атрибуте
[Column(TypeName = "varchar(200)")]
перезаписывает любое значение по умолчанию......
У меня нет установленной Rocket DB, поэтому я не могу ничего пробовать конкретно.
Но может быть
[Column(TypeName = "MD2")]
или
[Column(TypeName = "MR2")]
?
Если вы предпочитаете "свободно" использовать сопоставления ORM, это будет "HasColumnType".
https://www.learnentityframeworkcore.com/configuration/fluent-api/hascolumntype-method