如何让 Web API odatamodelbuilder 使用 EF fluent API 映射

Posted

技术标签:

【中文标题】如何让 Web API odatamodelbuilder 使用 EF fluent API 映射【英文标题】:How do you get a web API odatamodelbuilder to work with EF fluent API mappings 【发布时间】:2014-08-24 19:15:14 【问题描述】:

我使用 pocos 创建了一个相当简单的域模型。我已经使用EntityTypeConfiguration<TEnitityType> 类将这些映射到EF DB 上下文。这一切都很好。

我现在正在尝试使用ODataConventionModelBuilder 创建一个 OData V4 WebAPI 控制器端点,而这正是问题所在。在遇到不基于约定的关联之前,一切正常。但是我找不到让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);

        
    

有人知道我可以通过 ODataBuilder 或 Web API 使用这些 EntityTypeConfiguration 文件吗?

编辑

如果找到this page,这似乎表明我正在使用的 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);

但构建器没有配置属性。

【问题讨论】:

Fanstatic!,做了更多的谷歌搜索,“odata web api fluent data mapping”的排名最高的搜索结果现在是这个SO问题。 你有没有想过这个问题?我正在为同样的事情哭泣。 【参考方案1】:

两件事:

    我已经阅读了多个来源,以防止使用延迟加载和序列化;这基本上就是 OData; (它甚至使用了 system.runtime.serialization.datacontract 和 datamember 属性)

    我在从上下文显式加载以及在模型构建器中为 dbContext 定义导航属性方面取得了更大的成功。我了解您正在查看自定义的导航属性,但我相当确定这些是对 ODataModelBuilder 类有用的重写方法(它不需要太多并且需要更少的实体框架来工作)。在您已经提到使用 EF 的地方,我想这就是您将工作的方向,如果您不需要为模型名称命名,您可以使用约定命名为每个 Set 添加一个条目。

    EntitySet("routePrefixName")

在构建 EdmModel 时,它会连接您之前使用 Fluent 建立的关系。如果您确实必须向底层模型添加无关项,则应将每个类定义为 EntityType(),仅设置键。 EdmBuilder 可以使用温和的属性和键关联来附加到 ODataConventionModelBuilder 中的 EF 模型。

我已经挣扎和寻找了一段时间,似乎没有大量关于 .Net OData v4 的信息漂浮,可能是由于整个 force datetimeoffset 问题。

希望能有所帮助

【讨论】:

以上是关于如何让 Web API odatamodelbuilder 使用 EF fluent API 映射的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Web API 统一回传格式以及例外处理

如何让 PUT 和 DELETE 动词与 IIS 上的 Web API 一起使用

064Spring Boot如何让Web API自动生成文档,并解决swagger-annotations的API注解description属性废弃的问题

如何让 CORS 与 ASP.Net Core Web API 服务器 Angular 2 客户端一起工作

如何让会话在 Laravel api 路由中工作?

如何从烧瓶中调用另一个 web 服务 api