Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Linq联合算子_C#_Linq - Fatal编程技术网

C# Linq联合算子

C# Linq联合算子,c#,linq,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) {

我有以下方法:

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()
}
公共IList搜索(IList类型)
{    
IQueryable books=数据库.books;
如果(genres.Count>0)
{
书籍=书籍。包括(“流派”);
foreach(在流派中为int-genreId)
{
books=books.Union(books.Where(b=>b.Genres.Any(g=>g.Id==genreId));
}
}
还书
}

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

我认为你应该反过来做。也就是说,从体裁到这样的书:

return
    database
    .Genres
    .Where(g => genre.Contains(g.Id))
    .SelectMany(g => g.Books)
    .ToList();
public class Genre
{
    public Genre()
    {
        Books = new HashSet<Book>();
        //...
    }

    public virtual ICollection<Book> Books {get;set;}
    //... Other properties here
}
此代码假定存在一个导航属性,该属性从
流派
书籍
,如下所示:

return
    database
    .Genres
    .Where(g => genre.Contains(g.Id))
    .SelectMany(g => g.Books)
    .ToList();
public class Genre
{
    public Genre()
    {
        Books = new HashSet<Book>();
        //...
    }

    public virtual ICollection<Book> Books {get;set;}
    //... Other properties here
}
公共类体裁
{
公共体裁()
{
Books=新HashSet();
//...
}
公共虚拟ICollection图书{get;set;}
//……这里还有其他房产
}

我认为你应该反过来做。也就是说,从体裁到这样的书:

return
    database
    .Genres
    .Where(g => genre.Contains(g.Id))
    .SelectMany(g => g.Books)
    .ToList();
public class Genre
{
    public Genre()
    {
        Books = new HashSet<Book>();
        //...
    }

    public virtual ICollection<Book> Books {get;set;}
    //... Other properties here
}
此代码假定存在一个导航属性,该属性从
流派
书籍
,如下所示:

return
    database
    .Genres
    .Where(g => genre.Contains(g.Id))
    .SelectMany(g => g.Books)
    .ToList();
public class Genre
{
    public Genre()
    {
        Books = new HashSet<Book>();
        //...
    }

    public virtual ICollection<Book> Books {get;set;}
    //... Other properties here
}
公共类体裁
{
公共体裁()
{
Books=新HashSet();
//...
}
公共虚拟ICollection图书{get;set;}
//……这里还有其他房产
}
公共类测试
{
私有列表书籍=新列表()
{
新书
{
Id=1,
类型=新列表()
{
新体裁
{
Id=1
},
新体裁
{
Id=2
}
}
},
新书
{
Id=2,
类型=新列表()
{
新体裁
{
Id=3
}
}
}
};
公共IList搜索(IList类型)
{
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);
    }
}
[TestClass]
公共类UnitTest1
{
试验t;
[测试初始化]
public void TestInitialize()
{
t=新测试();
}
[测试方法]
public void TestGetBooksByGenre()
{
var result=t.Search(新列表()
{
1.
});
Assert.IsTrue(result.Count==1);
Assert.IsTrue(结果[0].Id==1);
}
}
公共类测试
{
私有列表书籍=新列表()
{
新书
{
Id=1,
类型=新列表()
{
新体裁
{
Id=1
},
新体裁
{
Id=2
}
}
},
新书
{
Id=2,
类型=新列表()
{
新体裁
{
Id=3
}
}
}
};
公共IList搜索(IList类型)
{
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);
    }
}
[TestClass]
公共类UnitTest1
{
试验t;
[测试初始化]
public void TestInitialize()
{
t=新测试();
}
[测试方法]
public void TestGetBooksByGenre()
{
var result=t.Search(新列表()
{
1.
});
Assert.IsTrue(result.Count==1);
Assert.IsTrue(结果[0].Id==1);
}
}

你说的停下来工作是什么意思?此时将解析查询,因此如果查询花费的时间太长,它将停留在那里,直到结果就绪。要获得更好的方法,请查看
.Contains
如果您的意思是调试时无法运行下一行,请在它之间放置一个
try catch
,并获取异常消息以查看错误。我要注意
books.Union(books.Where(anyLambda))
最多只能与
books.Distinct()相同
因为除了任何
联合中固有的
Distinct()
之外,它还在
书籍
中添加了那些符合标准且不在
书籍
中的元素。因为显然
书籍
中的所有元素都已经在
书籍
中了,所以这似乎是一种复杂的方式来尝试
公共IQueryable搜索(IEnumerable流派){返回books.Include(“流派”)。其中(b=>b.Genres.Any(g=>genre.Contains(g.Id));}可能带有
Include(“流派”)`不需要。@Jonhana:差不多了。
if
仍然需要存在,因为如果没有指定类型,将返回完整的图书列表。(我假设在这种情况下,
type
是一个可选的过滤器,可以省略。)停止工作是什么意思?查询将在该点解析,因此如果查询花费的时间太长,它将停留在那里直到结果准备就绪。要更好地执行此操作,请查看
.Contains
,如果您的意思是调试时下一行不会运行,请在查询之间放置一个
try catch
,并获取异常消息以查看错误我注意到,
books.Union(books.Where(anyLambda))
充其量与
books.Distinct()相同,因为除了固有的
Distinct()之外
在任何
联合体中
都是在
书籍
中添加符合条件且不在
书籍
中的元素。因为显然
书籍
中的所有元素都已在
书籍
中,这似乎是尝试
公共可查询搜索的一种复杂方式(IEnumerable流派){返回书。包括(