EF6 -> EFCore ExecuteSqlCommand equivelant - PullRequest
0 голосов
/ 28 февраля 2020

Я работаю над переводом нашей модели на EF Core, и мне не удается найти способ вызвать следующий код:

InitializeTime = context.ExecuteSqlCommand<DateTime>("SELECT CURRENT_TIMESTAMP FROM DUAL").FirstOrDefault();

Мы используем время базы данных для синхронизации всего, кроме Я могу обнаружить, что вызов raw sql вне DbSet недоступен, а тип возвращаемого значения ограничен аргументом типа DbSet.

Я осмотрелся и обнаружил, что есть DbQuery объекты ( Статья ) но это похоже на тяжелую работу, чтобы получить текущую системную дату и время.

Кто-нибудь еще сталкивался с этим и нашел более простое решение?

Примечание: это настольное приложение, поэтому код будет работать на стороне клиента, а системная дата и время не будут надежными.

Ответы [ 2 ]

1 голос
/ 03 марта 2020

На случай, если кто-то столкнется с той же проблемой. Я получил следующее:

Создайте новый класс, содержащий свойство DateTime

public class SystemDateTime
{
    /// <summary>
    /// System datetime from the server.
    /// </summary>
    public DateTime DateTime { get; set; }
}

Добавьте DbSet типа SystemDateTime к модели

    /// <summary>
    /// Set for getting the current date time from the database.
    /// </summary>
    public DbSet<SystemDateTime> SystemDateTimes { get; set; }

Примечание: в EFCore 3.1 он должен иметь тип DbSet, но в EFCore 2.? этому типу набора посвящен другой тип, называемый DbQuery. См. Статью Здесь .

Добавьте сопоставление для конструктора моделей

modelBuilder.Entity<SystemDateTime>().HasNoKey();
modelBuilder.Entity<SystemDateTime>().Property<DateTime>(x => x.DateTime).HasColumnName(@"DateTime").HasColumnType(@"TIMESTAMP").IsRequired().ValueGeneratedNever();

Использование DbSet ' s FromSqlRaw для запроса к базе данных

List<SystemDateTime> systemDateTime = context.SystemDateTimes.FromSqlRaw("SELECT TO_CHAR (SYSDATE, 'MM-DD-YYYY HH24:MI:SS') \"DateTime\" FROM DUAL").ToList();

Это вернет список из одного элемента, поэтому используйте First() или Single, чтобы получить необходимое значение.

1 голос
/ 01 марта 2020

Тезки EFCore context.Database.ExecuteSqlRaw(sql) / context.Database.ExecuteSqlRInterpolated(sql) (или context.Database.ExecuteSqlCommand(sql) до EFCore 3, вы не указали, с какой версией вы работаете) могут только возвращать int, количество строк, на которые влияет выполнение оператора sql.

context.Query<TQuery>() (до EFCore 3, не рекомендуется с EFCore 3 и далее) или объект без ключа (EFCore 3 и далее), поддерживаемый обычным POCO, - ваши варианты, насколько мне известно знать, если вы хотите использовать EFCore для выполнения запроса.

Типы объектов без ключа doco:

Использование сценария ios

Некоторые основного сценария использования ios для типов ключей без ключа:

Служит типом возврата для необработанных SQL запросов.

С точки зрения издержек, это не совсем когда вы думаете о единицах работы / шаблоне хранилища, которые реализует EFCore; это по сути вынуждает вас создавать хранилище, а не выполнять ad-ho c запросы по всему месту.

...