c# entity framework 与虚拟 属性 查询
c# entity framework with virtual property query
我有这个class:
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; }
}
我想获取联系人的 table,因为消息是虚拟的并且所有延迟加载的东西,
这个电话对我不起作用,出现了这个错误:
The ObjectContext instance has been disposed and can no longer be used
for operations that require a connection. in Reference Table
语法:
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 时,我都会为它创建一个函数并将其放入 using(db)
像这样:
public class MessageService
{
ReadingFromData db = new ReadingFromData();
public ObservableCollection<Model.Message> LoadMessages()
{
using (db)
{
//Do something with db
}
}
}
此外,有人可以向我解释这是如何工作的,以及如何使用 entity framework 正确查询
谢谢
首先你要明白这段代码不查询数据库:
var x = from qr in db.Messages
orderby qr.Subject
select qr;
它只是一个查询定义(表达式),应该翻译成 SQL 并在您执行它时 发送到数据库服务器 。执行是枚举查询结果,或使用具有立即执行类型的 LINQ 运算符之一(请参阅 Classification of Standard Query Operators by Manner of Execution)。 IE。当稍后在代码中枚举 x
或尝试将查询结果存储在列表中时,数据库上下文 db
可能已被释放。当然,你会得到一个错误
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
将 return 某种类型 MessageWithDbContext
的实体,内部存储了 db
值。在 以后 进行额外的 'lazy' 数据库查询时需要它。再一次,如果在那个时间点数据库上下文被释放,那么你会得到一个异常:
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
如何解决这个问题?要么确保在您使用查询和进行额外的 'lazy' 调用时未释放数据库上下文。或者像第二个示例中那样使用 eager loading。预先加载允许您在执行查询时加载相关实体:
// 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();
在这种情况下,不需要额外的 'lazy' 调用,因此您可以处理数据库上下文并处理查询结果。
仅当在与上下文的连接打开(或未释放)的情况下访问 属性 时,延迟加载才会起作用。
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();
我有这个class:
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; }
}
我想获取联系人的 table,因为消息是虚拟的并且所有延迟加载的东西,
这个电话对我不起作用,出现了这个错误:
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection. in Reference Table
语法:
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 时,我都会为它创建一个函数并将其放入 using(db)
像这样:
public class MessageService
{
ReadingFromData db = new ReadingFromData();
public ObservableCollection<Model.Message> LoadMessages()
{
using (db)
{
//Do something with db
}
}
}
此外,有人可以向我解释这是如何工作的,以及如何使用 entity framework 正确查询
谢谢
首先你要明白这段代码不查询数据库:
var x = from qr in db.Messages
orderby qr.Subject
select qr;
它只是一个查询定义(表达式),应该翻译成 SQL 并在您执行它时 发送到数据库服务器 。执行是枚举查询结果,或使用具有立即执行类型的 LINQ 运算符之一(请参阅 Classification of Standard Query Operators by Manner of Execution)。 IE。当稍后在代码中枚举 x
或尝试将查询结果存储在列表中时,数据库上下文 db
可能已被释放。当然,你会得到一个错误
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
将 return 某种类型 MessageWithDbContext
的实体,内部存储了 db
值。在 以后 进行额外的 'lazy' 数据库查询时需要它。再一次,如果在那个时间点数据库上下文被释放,那么你会得到一个异常:
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
如何解决这个问题?要么确保在您使用查询和进行额外的 'lazy' 调用时未释放数据库上下文。或者像第二个示例中那样使用 eager loading。预先加载允许您在执行查询时加载相关实体:
// 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();
在这种情况下,不需要额外的 'lazy' 调用,因此您可以处理数据库上下文并处理查询结果。
仅当在与上下文的连接打开(或未释放)的情况下访问 属性 时,延迟加载才会起作用。
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();