C# 具有虚拟属性查询的c实体框架
我有这门课:C# 具有虚拟属性查询的c实体框架,c#,entity-framework,linq-to-entities,C#,Entity Framework,Linq To Entities,我有这门课: public class Message { public Message() { Contacts = new List<Contact>(); } public Message(string Sub_Message, string Body_Message, string Date_Send_Message) { Cont
public class Message
{
public Message()
{
Contacts = new List<Contact>();
}
public Message(string Sub_Message, string Body_Message, string Date_Send_Message)
{
Contacts = new List<Contact>();
Subject = Sub_Message;
Body = Body_Message;
Date = Date_Send_Message;
}
public int MessageId { get; set; }
public string Subject { get; set; }
public string Date { get; set; }
public string Body { get; set; }
public virtual IList<Contact> Contacts { get; set; }
}
我想得到联系人的表格,因为消息是虚拟的,所有的延迟加载的东西
此呼叫对我无效,出现以下错误:
ObjectContext实例已被释放,无法再使用
用于需要连接的操作。在参考表中
语法:
public ObservableCollection<Model.Message> LoadMessages()
{
using (db) {
var x = from qr in db.Messages
order by qr.Subject
select qr;
}
}
虽然这样做有效:
public ObservableCollection<Model.Message> LoadMessages()
{
using (db)
{
var Messages = db.Messages.Include(z => z.Contacts).ToList();
return new ObservableCollection<Model.Message>(Messages);
}
}
因此,我在一个名为MessageService的服务中使用查询,每次我想要使用dbContext时,我都会为它创建一个函数,并将其放入usingdb中
像这样:
public class MessageService
{
ReadingFromData db = new ReadingFromData();
public ObservableCollection<Model.Message> LoadMessages()
{
using (db)
{
//Do something with db
}
}
}
另外,有人能给我解释一下这是如何工作的,以及如何使用实体框架查询吗
谢谢首先,您应该了解此代码不会查询数据库:
var x = from qr in db.Messages
orderby qr.Subject
select qr;
它只是一个查询定义表达式,应该将其转换为SQL并在执行时发送到数据库服务器。执行是枚举查询结果,或使用具有立即执行类型的LINQ运算符之一,请参阅。也就是说,当稍后在代码中枚举x或尝试将查询结果存储在列表中时,可能已经释放了数据库上下文数据库。当然,你会得到一个错误
var x = db.Messages; // query is not executed
db.Dispose(); // context disposed
foreach(var m in x) // exception here, you try to execute query which uses disposed context
...
现在谈谈延迟加载。它的工作原理是将数据库上下文存储在从实体继承的代理实体中。因此,实际上db.Messages将返回某种类型的实体MessageWithDbContext,其中db值存储在内部。它是以后进行其他“惰性”数据库查询所必需的。同样,如果此时数据库上下文被释放,那么您将得到一个异常:
var x = db.Messages.ToList(); // query is executed, messages are loaded
db.Dispose(); // context disposed
foreach(var m in x)
m.Contacts.Count(); // exception - you try to execute contacts query with disposed db
如何解决这个问题?在处理查询和进行其他“惰性”调用时,请确保未释放数据库上下文。或者像在第二个示例中那样使用即时加载。即时加载允许您在执行查询时加载相关实体:
// both messages and contacts are loaded from database when you execute the query
var x = db.Message.Include(m => m.Contacts).ToList();
db.Dispose();
foreach(var m in x)
m.Contacts.Count();
在这种情况下,不需要额外的“延迟”调用,因此您可以处理数据库上下文并处理查询结果。只有在打开或未处理与上下文的连接时访问属性时,延迟加载才会起作用
using (db)
{
//If you try to load the data here, lazy loading will work.
}
现在,当您使用include时,EF会立即加载并为您获取相关数据。这就是为什么在使用include时数据可用的原因
var Messages = db.Messages.Include(z => z.Contacts).ToList();
请提供一些代码来说明如何使用上下文。如果连接关闭,延迟加载将不起作用。编辑后@HarshSo-eanger-loading立即获得结果,而不是等待执行?@Zakk-eanger-loading将获得相关实体,而不等待您需要它们。如果您不执行查询,则可以延迟查询本身,例如,使用ToList调用,请参阅第一个example@SergeyBerezovskiy一个问题是,为什么每个人都想在类中保存集合时使用公共虚拟ICollection,为什么它不只是公共列表myList?