【问题标题】:Returning view model from OData web api with EF使用 EF 从 OData Web api 返回视图模型
【发布时间】:2015-12-27 05:04:36
【问题描述】:

我正在尝试从 ODataController 返回自定义视图模型。这是视图模型:

public class TaskViewModel
{
    public int TaskID { get; set; }
    public string Name { get; set;}
    public string Details { get; set; }
    public DateTime? DueDate { get; set; }
    public virtual Project Project { get; set; }
}

我的控制器如下所示:

public IEnumerable<TaskViewModel> Get(ODataQueryOptions<TaskViewModel> options)
{
    IEnumerable<Task> tasks = db.Tasks.AsEnumerable();
    ...
    var vm = from t in tasks
             select new TaskViewModel
             {
                 TaskID = t.TaskID,
                 Name = t.Name,
                 Details = t.Details,
                 DueDate = t.DueDate,
                 Project = t.Project
             }
    return vm.AsEnumerable();
}

Task 实体如下所示(从数据库优先的 EDMX 生成):

public partial class Task
{
    public int TaskID { get; set; }
    public string Name { get; set; }
    public string Details { get; set; }
    public DateTime? DueDate { get; set; }
    ... //other properties I don't want exposed
    public virtual Project Project { get; set; }
}

当我尝试执行 GET 时,我收到以下消息:

“在实体集‘Tasks’上从实体类型‘MyApplication.ViewModels.TaskViewModel’的导航属性‘Project’中找不到 NavigationLink 工厂。尝试在 EntitySetConfiguration 上调用 HasNavigationPropertyLink。”

这是我的 WebApiConfig.cs:

builder.EntitySet<Project>("Projects").EntityType.HasKey(p => p.ProjectID);
builder.EntitySet<Task>("Tasks").EntityType.HasKey(t => t.TaskID);
...
builder.EntitySet<ViewModels.TaskViewModel>("TaskViewModel");

我已经成功地使用应用程序(项目)中的另一个实体完成了此操作,所以我不知道为什么这个不工作。唯一的区别是 Task 实体引用了 Project 实体。

感谢任何帮助/见解。

【问题讨论】:

  • 您的数据库中是否有任何名为TaskViewModel 的表?
  • 不,它不是数据库的一部分。但是,我能够成功使用 ProjectViewModel 类而无需将其添加到数据库中。
  • 那你为什么要在你的配置中应用builder.EntitySet&lt;ViewModels.TaskViewModel&gt;("TaskViewModel"); 行?
  • 我读过的所有东西都说必须在里面。如果我把它拿出来,我会收到错误:“给定的模型不包含类型'MyApplication.ViewModels.TaskViewModel'。

标签: c# entity-framework odata asp.net-web-api2 asp.net-web-api


【解决方案1】:

我能够让它工作。我所做的只是让 TaskViewModel 类成为 Task 的派生类。

发件人:

public class TaskViewModel
{
    public int TaskID { get; set; }
    ...
    public string CurrentStatus { get; set; }
}

收件人:

public class TaskViewModel : Task
{
    public string CurrentStatus { get; set; }
}

还值得注意的是,无论是否有 WebApiConfig.cs 中的 TaskViewModel 条目,这都适用。

【讨论】:

  • 让您的 DTO 从您的域模型派生远非理想
  • 抱歉删除了这个帖子,但是有没有人找到一个更简洁的最佳解决方案?
  • @Cocowalla 你为什么这么说?
  • @Badulake 因为 DTO 的主要原因之一是视图通常需要与域模型提供的数据不同的数据,或者需要扁平化、格式化、解析或其他不同格式的数据
  • @Badulake 我仍然会使用不从我的域模型继承的 DTO,并且我会使用 AutoMapper 或类似工具为我完成将属性映射到 DTO 的猴子工作
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-04
相关资源
最近更新 更多