Публикация значения времени в базу данных 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 использовать его (вместо того, чтобы полагаться на значения по умолчанию)

https://docs.microsoft.com/en-us/ef/core/modeling/entity-properties?tabs=data-annotations%2Cfluent-api%2Cwithout-nrt

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

Другие вопросы по тегам