简体   繁体   English

如何声明匿名类型列表

[英]How to declare List of anonymous type

In this official ASP.NET MVC Core tutorial they have defined a ViewModel as follows where Movie is a class. 在此官方ASP.NET MVC Core教程中,他们定义了如下ViewModel,其中Movie是类。 Then in the Index(...) method (towards the end of the tutorial they are populating the ViewModel from a simple LINQ query as shown in the Controller below: 然后在Index(...)方法中(在本教程结束时,他们从一个简单的LINQ查询中填充ViewModel,如下面的Controller中所示):

ViewModel : ViewModel

public class MovieGenreViewModel
{
    public List<Movie> movies;
    public SelectList genres;
    public string movieGenre { get; set; }
}

Controller : 控制器

public async Task<IActionResult> Index(string movieGenre, string searchString)
{
    // Use LINQ to get list of genres.
    IQueryable<string> genreQuery = from m in _context.Movie
                                    orderby m.Genre
                                    select m.Genre;

    var movies = from m in _context.Movie
                 select m;

    if (!String.IsNullOrEmpty(searchString))
    {
        movies = movies.Where(s => s.Title.Contains(searchString));
    }

    if (!String.IsNullOrEmpty(movieGenre))
    {
        movies = movies.Where(x => x.Genre == movieGenre);
    }

    var movieGenreVM = new MovieGenreViewModel();
    movieGenreVM.genres = new SelectList(await genreQuery.Distinct().ToListAsync());
    movieGenreVM.movies = await movies.ToListAsync();

    return View(movieGenreVM);
}

Question : In the above ViewModel the property movies was of type List<movie> and the query used in the Index(...) method was a simple query involving just one table (movies). 问题 :在上述ViewModel中,属性影片的类型为List<movie> ,而Index(...)方法中使用的查询是仅包含一个表(影片)的简单查询。 But what if the query involves an INNER JOIN with two tables and hence returns an object of anonymous type as shown below. 但是,如果查询涉及具有两个表的INNER JOIN并因此返回匿名类型的对象,如下所示,该怎么办? In that case how would we declare a list of anonymous type List<.?.> in a ViewModel and then populate that property of type List<.?.> in the ViewModel? 在那种情况下,我们如何在ViewModel中声明匿名类型List<.?.> ,然后在ViewModel中填充List <。?。>类型的属性? In the example below I defined a ViewModel with List<dynamic> or List<object> and tried myViewModel.list = leftOuterJoinQuery.ToListAsync() but got the error as Cannot implicitly convert type 'List<<anonymous type: int CategoryId, string CategoryName, string ProdName>>>' to 'System.Collections.Generic.List<dynamic> : 在下面的示例中,我使用List<dynamic>List<object>定义了一个ViewModel,并尝试了myViewModel.list = leftOuterJoinQuery.ToListAsync()但由于Cannot implicitly convert type 'List<<anonymous type: int CategoryId, string CategoryName, string ProdName>>>' to 'System.Collections.Generic.List<dynamic>而收到错误Cannot implicitly convert type 'List<<anonymous type: int CategoryId, string CategoryName, string ProdName>>>' to 'System.Collections.Generic.List<dynamic>

LINQ INNER JOIN Query : LINQ INNER JOIN查询

var innerJoinQuery =
    from category in categories
    join prod in products on category.ID equals prod.CategoryID
    select new { ProductName = prod.Name, Category = category.Name }; //produces flat sequence

UPDATE : 更新

As @StephenMuecke suggested below, the problem can be solved by creating another View Model containing the properties returned by my query. 如下@StephenMuecke所建议,可以通过创建另一个包含我的查询返回的属性的视图模型来解决该问题。 But I'm thinking if there is a way to avoid creating an extra View Model. 但是我在考虑是否有办法避免创建额外的视图模型。

There is way to accomplish it without creating new VM, but i'm not sure it is the right way. 有一种无需创建新VM即可完成此操作的方法,但是我不确定这是正确的方法。

First, I'll turn the VM as below 首先,我将如下所示切换虚拟机

public class MovieGenreViewModel
{
    public ICollection movies;
    public SelectList genres;
    public string movieGenre { get; set; }
}

Define a helper method to compose list from anonymous objects 定义一个辅助方法来组成匿名对象的列表

public static List<T> CreateList<T>(params T[] elements)
{
     return new List<T>(elements);
}

Finally, change the line inside Index() method 最后,更改Index()方法内的行

from

movieGenreVM.movies = await movies.ToListAsync();

to

   var output = await innerJoinQuery.ToListAsync();
   movieGenreVM.movies = CreateList(output);

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM