c# - 在单个 View 模型上使用 LINQ to "transform"两个模型

标签 c# .net entity-framework linq

我正在 ASP.NET 上创建一个页面并想将一些模型 (EF) 传递给 View 。 此 View 包含来自两个不同模型的信息,因此,我为此创建了一个 ViewModel。

首先,我的两个模型:

public class Database
{
  public int Id { get; set; }
  public string Name { get; set; }
  public string Host { get; set; }
  public string Schema { get; set; }
  public ICollection<Group> Groups { get; set; }
}

public class Group
{
  public int Id { get; set; }
  public string Name { get; set; }
  public ICollection<Database> Databases { get; set; }
}

所以,看看我的模型,我有一个 Database 有一个或多个 Group,而 Group 有一个或多个 数据库,所以,是多对多的关系。

我的 View 显示一个表单,其中包含来自 Database 模型的所有字段,以及一个包含所有 Group 的复选框列表,以及此 Group 是否属于到 Database,复选框被选中。

因此,我创建了以下 View 模型(欢迎提出建议):

public class DatabaseViewModel
{
  public Database Database { get; set; }
  public List<DatabaseGroupViewModel> Groups { get; set; }
}

public class DatabaseGroupViewModel
{
  public Group Group { get; set; }
  public bool Selected { get; set; }
}

我“直接”使用了 DatabaseGroup,因为这是一个 CRUD 表单,并且已经在模型上进行了验证(数据注释)。这里的思路是获取Database,以及所有的Group,如果这个Group属于Database,则Selected 属性必须为 true

到目前为止一切顺利。

我使用以下代码列出所有 Group,如果 Group,则将 Selected 属性设置为 true属于数据库

int databaseId = 1; // just for example
DatabaseViewModel model = new DatabaseViewModel
{
  Database = await Context.Databases.FirstOrDefaultAsync(d => d.Id == databaseId),
  Groups = Context.Groups.Include(d => d.Databases).OrderBy(g => g.Name).Select(g => new DatabaseGroupViewModel
  {
    Group = g,
    Selected = g.Databases.Any(d => d.Id == databaseId)
  }).ToList()
};

这似乎可行,但我不知道这是否是最佳方法。

有什么帮助吗?

编辑:现在工作代码

最佳答案

EF 将您的 linq 表达式转置为 SQL 以查询数据库,但并非所有内容都可以表示为 SQL - “LINQ to Entities 无法识别该方法……”是您在使用 EF 无法转置的内容时遇到的错误到查询中的 SQL。

如果您首先使用 .ToList() 加载值,则不会出现此错误,因为表达式将在内存中求值。请注意,这会将数据从数据库拉入内存,因此在使用 ToList() 调用实现实体之前,您应该尽可能限制使用 EF 支持的表达式选择的数据。

但是,在这种情况下,它是在 linq 表达式中使用 Context.Databases,我认为您可以通过使用已经进入 Select 参数的 Group 参数来完全避免这种情况:

int databaseId = 1; // just for example
DatabaseViewModel model = new DatabaseViewModel
{
  Database = await Context.Databases.FirstOrDefaultAsync(d => d.Id == databaseId),
  Groups = Context.Groups.OrderBy(g => g.Name).Select(g => new DatabaseGroupViewModel
  {
    Group = g,
    Selected =  g.Databases .Any(db => db.Id == databaseId)
  }).ToList()
};

关于c# - 在单个 View 模型上使用 LINQ to "transform"两个模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44032223/

相关文章:

c# - 如何在 C# 中创建可点击的不规则形状区域

c# - 选择进入表命令在 C# 中不起作用

c# - 镜像网格和错误的 UV 贴图运行时导出

.net - 如何从 .net core 调用 ibm watson api

c# - AutoMapper 在 IQueryable 上调用 ProjectTo<T>() 时抛出 StackOverflowException

c# - 通用工作单元

c# - MSBuild SonarQube Runner Resharper 插件收到跳过信息错误文件不在 sonarqube 中

.Net 加密

.net - Visual Basic 的 .Net 4.5 有哪些新功能?

entity-framework - 如何为 Breeze 实体生成 typescript 接口(interface)/定义