Linq Union运营商

时间:2016-01-16 10:03:51

标签: c# linq

我有以下方法:

public IList<Book> Search(IList<int> genre)
{    
    IQueryable<Book> books = database.Books;
    if (genres.Count > 0)
    {
        books = books.Include("Genres");
        foreach (int genreId in genres)
        {
            books = books.Union(books.Where(b => b.Genres.Any(g => g.Id == genreId)));
        }
    }
    return books.ToList()
}

停止在最后一行工作。为什么?也许有人知道更有效的方法来获得属于相应类型id的所有实体吗?

2 个答案:

答案 0 :(得分:2)

我认为你应该反过来做。即,从流派到这样的书:

return
    database
    .Genres
    .Where(g => genre.Contains(g.Id))
    .SelectMany(g => g.Books)
    .ToList();

此代码假定存在从GenreBook的导航属性,如下所示:

public class Genre
{
    public Genre()
    {
        Books = new HashSet<Book>();
        //...
    }

    public virtual ICollection<Book> Books {get;set;}
    //... Other properties here
}

答案 1 :(得分:0)

public class Test
{

    private List<Book> books = new List<Book>()
    {
        new Book
        {
            Id = 1,
            Genres = new List<Genre>()
            {
                new Genre
                {
                    Id = 1
                },
                new Genre
                {
                    Id = 2
                }
            }
        },
        new Book
        {
            Id = 2,
            Genres = new List<Genre>()
            {
                new Genre
                {
                    Id = 3
                }
            }
        }
    };

    public IList<Book> Search(IList<int> genres)
    {

        return books.Where(x => x.Genres.Any(y => genres.Contains(y.Id))).ToList();

    }

}

做了一个简单的例子。在功能搜索中,仅使用database.Books替换书籍。

测试验证结果。

[TestClass]
public class UnitTest1
{

    Test t;

    [TestInitialize]
    public void TestInitialize()
    {
        t = new Test();
    }

    [TestMethod]
    public void TestGetBooksByGenre()
    {
        var result = t.Search(new List<int>()
        {
            1
        });

        Assert.IsTrue(result.Count == 1);
        Assert.IsTrue(result[0].Id == 1);
    }
}