gpt4 book ai didi

具有虚拟属性查询的 c# Entity Framework

转载 作者:行者123 更新时间:2023-11-30 20:17:20 27 4
gpt4 key购买 nike

我有这门课:

    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; }
}

我想获取联系人表,因为 Messages 是虚拟的并且所有延迟加载的东西,

此调用对我不起作用并出现此错误:

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 将返回某种类型 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

如何解决这个问题?要么确保在您使用查询和进行额外的“惰性”调用时未处理数据库上下文。或者像第二个示例中那样使用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();

在这种情况下,不需要额外的“惰性”调用,因此您可以处理数据库上下文并处理查询结果。

关于具有虚拟属性查询的 c# Entity Framework ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44903910/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com