joh*_* Gu 14 linq entity-framework asp.net-mvc-3
我想创建一个Movie_Type
在我的ASP.NET MVC Web应用程序中命名的新模型对象.如果我将此类的导航属性定义为或者如下List
,那将会有什么不同?ICollection
IQueryable
public partial class Movie_Type
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public List<Movie> Movies { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
要么
public partial class Movie_Type
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public IQueryable<Movie> Movies { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
要么
public partial class Movie_Type
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public ICollection<Movie> Movies { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
编辑: -
@Tomas Petricek.感谢您的回复.在我的情况下,我使用数据库第一种方法,然后我使用DbContext
模板来映射我的表,这是自动创建ICollection
的所有导航属性,所以我的问题是: - 1.这是否意味着它并不总是最好的选择使用ICollection的.我应该更改自动生成的类以最适合我的情况.2.其次,我可以设法通过定义.include等来选择延迟或预先加载
var courses = db.Courses.Include(c => c.Department);
Run Code Online (Sandbox Code Playgroud)
无论我用什么来定义导航属性.所以我无法理解你的观点.3.我没有找到任何IQuerable
用于定义导航属性的示例或教程,那么可能是什么原因?BR
Sla*_*uma 15
您不能使用类型的导航属性IQueryable<T>
.您必须使用ICollection<T>
或某些实现的集合类型ICollection<T>
- 比如List<T>
.(IQueryable<T>
没有实施ICollection<T>
.)
导航属性只是内存中的对象或对象集合,null
或者集合是空的.
当您从数据库加载包含导航属性的父对象时,它永远不会从数据库加载.
您要么必须明确表示要将导航属性与急切加载的父项一起加载:
var movieTypes = context.Movie_Types.Include(m => m.Movies).ToList();
// no option to filter or sort the movies collection here.
// It will always load the full collection into memory
Run Code Online (Sandbox Code Playgroud)
或者它将通过延迟加载加载(如果您的导航属性是默认情况下启用virtual
):
var movieTypes = context.Movie_Types.ToList();
foreach (var mt in movieTypes)
{
// one new database query as soon as you access properties of mt.Movies
foreach (var m in mt.Movies)
{
Console.WriteLine(m.Title);
}
}
Run Code Online (Sandbox Code Playgroud)
最后一个选项是显式加载,我认为最接近你的意图:
var movieTypes = context.Movie_Types.ToList();
foreach (var mt in movieTypes)
{
IQueryable<Movie> mq = context.Entry(mt).Collection(m => m.Movies).Query();
// You can use this IQueryable now to apply more filters
// to the collection or sorting, for example:
mq.Where(m => m.Title.StartWith("A")) // filter by title
.OrderBy(m => m.PublishDate) // sort by date
.Take(10) // take only the first ten of result
.Load(); // populate now the nav. property
// again this was a database query
foreach (var m in mt.Movies) // contains only the filtered movies now
{
Console.WriteLine(m.Title);
}
}
Run Code Online (Sandbox Code Playgroud)
有两种可能的方式来看待事物:
结果是作为对象实例的一部分存储在内存中的吗?
如果您选择ICollection
,结果将存储在内存中 - 如果数据集非常大或者您并不总是需要获取数据,这可能不是一个好主意.另一方面,当您将数据存储在内存中时,您将能够从程序中修改数据集.
您可以优化发送到SQL服务器的查询吗?
这意味着您可以在返回的属性上使用LINQ,并且其他LINQ运算符将转换为SQL - 如果您不选择此选项,则额外的LINQ处理将在内存中运行.
如果要将数据存储在内存中,则可以使用ICollection
.如果您希望能够优化查询,则需要使用IQueryable
.这是一个摘要表:
| | Refine query | Don't change query |
|-----------------|--------------|--------------------|
| In-memory | N/A | ICollection |
| Lazy execution | IQueryable | IEnumerable |
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5113 次 |
最近记录: |