#entity-framework #odata #asp.net-web-api
#entity-framework #odata #asp.net-web-api
Вопрос:
Я создал довольно простую модель предметной области, используя pocos. Я сопоставил их с контекстом EF DB с помощью EntityTypeConfiguration<TEnitityType>
классов. Все это работает нормально.
Сейчас я пытаюсь создать конечную точку контроллера OData V4 WebAPI, используя ODataConventionModelBuilder
и вот тут-то все и отклеивается. Все работает нормально, пока не столкнется с ассоциацией, не основанной на соглашении. Но я не могу найти способ заставить ODataBuilder
получать сопоставления из моих EntityTypeConfiguration<TEnitityType>
классов.
Это оставляет мне 2 неприятных варианта
- Украсьте мои прекрасные чистые pocos грязными атрибутами.
- Повторно сопоставьте все сопоставления, не основанные на соглашениях, вручную, используя
ODataBuilder
Не уверен, помогут ли примеры кода, но в любом случае они здесь, я упростил сущности для краткости.
var builder = new ODataConventionModelBuilder();
builder.EntitySet<Item>("Items");
config.MapODataServiceRoute(
routeName: "odata",
routePrefix: "odata",
model: builder.GetEdmModel(),
batchHandler: new DefaultODataBatchHandler((GlobalConfiguration.DefaultServer)));
public class Item
{
public Int32 Id { get; set; }
public Int16 ItemTypeId { get; set; }
public virtual ItemType Type { get; set; }
public virtual ICollection<ItemVersion> Versions { get; set; }
public virtual ICollection<ItemTag> Tags { get; set; }
}
Проблема возникает, когда он сталкивается с коллекцией ItemTags, вот ItemTag:
public class ItemTag
{
public Int32 ItemId { get; set; }
public string Tag { get; set; }
public Item Item { get; set; }
}
Который, как вы можете видеть, не основан на соглашениях, и у меня есть класс конфигурации для него следующим образом:
public class ItemTagConfiguration : EntityTypeConfiguration<ItemTag>
{
public ItemTagConfiguration()
{
HasKey(x => new {x.ItemId, x.Tag});
HasRequired(x => x.Item)
.WithMany(y => y.Tags)
.HasForeignKey(x => x.ItemId);
}
}
Кто-нибудь знает способ, которым я могу использовать эти EntityTypeConfiguration
файлы с помощью ODataBuilder или web API?
Редактировать
Если найдена эта страница, которая, кажется, указывает, что это может быть возможно с EF 6, который я использую. Что я хочу сделать, так это
ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<Dbf>("Dbfs");
// modelBuilder.Configurations.Add(new DbfMap()); <---- NO GOOD - Needs Class from DBContext we only have a model builder :(
Microsoft.Data.Edm.IEdmModel model = modelBuilder.GetEdmModel();
config.Routes.MapODataRoute("ODataRoute", "odata", model);
но у конструктора нет свойства Configuration.
Комментарии:
1. Fanstatic!, еще немного поискал в Google, и результатом поиска с наивысшим рейтингом для «odata web api fluent data mapping» теперь является этот вопрос SO.
2. Вы когда-нибудь понимали это? Я выплакиваю глаза из-за того же самого.
Ответ №1:
Две вещи:
-
Теперь я прочитал несколько источников, которые предостерегают от использования отложенной загрузки и сериализации; по сути, это и есть OData; (Он даже использует атрибуты system.runtime.serialization.datacontract и datamember)
-
Я добился большего успеха в явной загрузке из контекста и определении свойств навигации в modelbuilder для DbContext. Я понимаю, что вы смотрите на настраиваемые свойства навигации, но я совершенно уверен, что это переопределенные методы, полезные для класса ODataModelBuilder (который не требует многого и требует меньше Entity Framework для работы). Где вы уже упоминали использование EF, я полагаю, что это направление, в котором вы будете работать, и если вам не нужно указывать псевдонимы имен ваших моделей, вы добавляете запись для каждого набора, используя условное обозначение.
EntitySet(«routePrefixName»)
при построении EdmModel, и это связывает отношения, которые вы создали с помощью Fluent ранее. Если вам действительно нужно добавить посторонние элементы в базовую модель, вы должны определить каждый класс как EntityType<>(), установив только ключ. EdmBuilder может использовать мягкие свойства и ассоциацию ключей для присоединения к модели EF в ODataConventionModelBuilder.
Я некоторое время боролся и искал, и, похоже, не существует большого количества информации о .Net OData v4, вероятно, из-за всей проблемы force datetimeoffset.
Надеюсь, это немного поможет