我曾经为我的ASP.NET站点安装了一个WORKING数据库,直到我了解到在整个应用程序生命周期中使用静态数据库上下文对象是非常糟糕的做法。
所以,最初,我曾经有这个:
public class Database
{
MainDBContainer db;
static Database()
{
db = new MainDBContainer();
}
}
internal static SiteUser GetUser(string username)
{
return db.SiteUserSet.SingleOrDefault(u => u.Username == username);
}
而且,正如您可能猜到的,我一直使用此静态对象来访问/修改数据库。好吧,因为我到处都读到了(静态数据库上下文很糟糕),我决定将代码更改为:
internal static SiteUser GetUser(string username)
{
//notice no static constructor for class.
using (MainDBContainer db = new MainDBContainer())
{
return db.SiteUserSet.SingleOrDefault(u => u.Username == username);
}
}
这段代码的问题(不是特别“这个”非常代码,而是修改某些内容的代码。通过这意味着,我的意思是我使用using关键字封装每个数据库访问权限就像这一样),{{1}调用它,它不会抛出任何异常,但也没有任何反应。在同一个环境中,一切正常,但就是这样。 没有写到实际的SQL数据库。之前,我已经设置好所有工作,只要调用了when db.SaveChanges()
,就会立即将所有内容刷新到数据库中。我的用户身份验证甚至被破坏了(直截了当:客户端发送用户名/密码哈希,如果其右侧服务器发送随机令牌,客户端对每个请求使用令牌):用户调用登录方法并成功获取令牌,但每当任何其他代码交互时使用User对象,来自另一个上下文,令牌是DB之前拥有的任何内容,并且login方法中的SaveChanges()
无效。对于所有方法都是一样的,我只是将Login一个作为一个简单的例子。我错过了什么吗?在移植代码时我是否遗漏了一些明显的东西?可能是的,但它是什么?
谢谢, 可以。
答案 0 :(得分:1)
您已转移到断开连接的模型。当上下文被销毁时,EF在下一次CRUD操作中创建新实例时不再知道哪些对象关联。基本上,您需要手动告诉EF有关要保留的对象以及如何保留它们。
要保存,您需要在上下文中调用AddObject
。
要进行更新,请在AttachTo
上致电ChangeObjectState
然后SetModifiedProperty
或ObjectStateManager
。 (注意:这仅适用于完全断开连接的对象:如果加载对象然后进行更改 - 如果您正在进行行级版本控制,则可能会执行某些操作 - EF已知道该怎么做因为它有一个内置的变更跟踪机制,但只有当对象连接时。)
要进行删除,请致电AttachTo
,然后致电DeleteObject
。