C# 使用LINQ来;“转变”;单视图模型上的两个模型

C# 使用LINQ来;“转变”;单视图模型上的两个模型,c#,.net,entity-framework,linq,C#,.net,Entity Framework,Linq,我正在ASP.NET上创建一个页面,希望将一些模型(EF)传递给视图。 此视图包含来自两个不同模型的信息,因此,我为此创建了一个ViewModel 首先,我的两个模型: public class Database { public int Id { get; set; } public string Name { get; set; } public string Host { get; set; } public string Schema { get; set; } pu

我正在ASP.NET上创建一个页面,希望将一些模型(EF)传递给视图。 此视图包含来自两个不同模型的信息,因此,我为此创建了一个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; }
}
我“直接”使用了
数据库
,因为这是一个CRUD表单,并且已经在模型上进行了验证(数据注释)。此处的ideia是获取
数据库
,以及所有
,如果该
属于
数据库
,则所选的
属性必须为

到目前为止还不错

我使用以下代码列出所有
,如果
属于
数据库
,则将
选定的
属性设置为
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()
};

可能重复的请不要像您在此处所做的那样以更改问题的方式编辑您的问题。您最初的问题涉及不起作用的代码,您希望尝试使用这些代码。您的新问题完全改变了实现,并提出了与您最初提出的问题完全不同的问题。对不起,我的问题不是关于我的不工作代码,而是如果这种方法正确,如果不正确,如何使事情更“干净”。您最初的问题是关于您的“不工作代码”。这是我的观点。你现在有一个新的问题,它与你最初在这里发布的完全不同。如果你对此有任何疑问,请查看“清洁剂”。。。只需将
Context.Database.Include(d=>d.Groups)。首先(d=>d.Id==databaseId)
作为您的viewmodel
(Models.Database)
,并将可能的组放入Viewbag中。我必须包含
Context.Groups.Include(g=>g.Databases)
(惰性加载)@robertocoreia
。Include
用于快速加载,而不是惰性加载。如果不执行.Include,将发生延迟加载。不管怎样,它都可能会急于加载,因为它会确定在任何情况下都需要所选属性的数据库id,仅供参考。
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()
};