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流派){返回书。包括(