Spatial типы и EFCore

SleepyManiac
SleepyManiac Blog
Published in
1 min readSep 28, 2017

Как известно, EFCore по умолчанию не работает со Spatial типами. Тикет об их поддержке уже даавно лежит на гитхабе. Увы, скорее всего ждать полноценной поддержки придётся ещё долго. Но варианты есть! Ниже можно увидеть доступные нам опции.

  1. We go back in time. EF6 всё ещё есть, он работает, и в нём есть поддержка spatial типов через DbGeography и DbGeometry классы.
  2. Вооружившись знанием о том, что в efcore 2 появилась возможность определять свои type mappings, прикрутить поддержку SqlServerTypes. Этот вариант будет работать только на windows, зато очень удобен.

Именно второй вариант мы и будем рассматривать. Для начала, создадим свой type mapping:

Далее, нам нужно добавить в SqlServerTypeMapper новый маппинг. Расширяем класс:

Здесь можно озаботиться синхронизацией, но основная идея — переопределить методы GetClrTypeMappings и GetStoreTypeMappings добавив в них наш маппинг для географии.

Далее осталось подменить IRelationalTypeMapper сервис нашей реализацией. Можно это сделать в ConfigureServices методе, а можно в вашем контексте переопределить OnConfiguring:

protected override void OnConfiguring( DbContextOptionsBuilder optionsBuilder) { optionsBuilder .ReplaceService(); base.OnConfiguring(optionsBuilder); }

Всё? Почти.

Если вы используете InMemory провайдер для тестирования, вам нужно провернуть такую же фишку и в нём. К счастью, поддержка type mappings уже доступна. Здесь вам надо зарегистрировать в DI другой интерфейс (ITypeMapper вместо IRelationalTypeMapper). Загвоздка заключается в том, что при добавлении регистрации InMemoryDatabase через UseInMemoryDatabase не происходит регистрация класса RelationalTypeMapperDependencies, в итоге его нельзя просто подменить через ReplaceService. Что делать?

Создаём ещё одного наследника:

После чего мы в наших тестах мы можем делать следующее:

var context = new YourContext(new DbContextOptionsBuilder() .UseInMemoryDatabase(“Test”) .ReplaceService().Options);

Вуаля!

Originally published at blog.sleepymaniac.com on September 28, 2017.

--

--