gpt4 book ai didi

c# Entity Framework 什么时候应该使用新的 dbContext?

转载 作者:搜寻专家 更新时间:2023-10-30 19:47:37 26 4
gpt4 key购买 nike

有一段时间我想知道创建 dbcontext 的新实例的正确方法是什么?我遇到了一些问题,因为当我通过 SQL Server 在数据库中进行更改时,我的上下文不会更新数据。让我解释一下我的网站是如何工作的。

我们正在为我们的客户做一个预约网站,显然可以预约。我们将在我们的服务器上托管所有数据库。应用程序如何工作由 2 个连接组成:

第一次连接

这个连接一直连接到同一个数据库,我们称它为 master。它会使用示例中的 url 代码将用户重定向到良好的数据库:www.example.com/foo服务器将检查此处为 foo 的代码所以它会在表中查找以匹配代码,然后在应该重定向的地方获取正确的数据库名称,我的第二个连接就在这里

二次连接

这个会根据master返回的数据连接到正确的数据库。从这里开始,除了实际上从不更新的 DBContext 之外,一切似乎都运行良好,因为我没有正确实例化它并且我没有丰富的经验。这是我和同事一起做的代码:

using System;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Routing;
using WebRV.Models.Entities;

namespace WebRV.RouteDb
{

public class DbConnection
{

private static DbConnection instance;
private Cliniciel_WebRV_Entities db;
private String connectionString;
private readonly Cliniciel_WebRV_MasterEntities masterDb = new Cliniciel_WebRV_MasterEntities();
private Int32 idCie;
private static readonly object myLock = new object();


private DbConnection() {
var context = new HttpContextWrapper(System.Web.HttpContext.Current);
var routeData = RouteTable.Routes.GetRouteData(context);
// Use RouteData directly:
String code = routeData.Values["code"].ToString();
//String code = Thread.CurrentContext. .RequestContext.RouteData.Values["code"].ToString();
var response = masterDb.SYS_tbCustDBLocation.Where(p => p.CustDBLocationCode == code).ToList();

if (response.Count == 1)
{
try
{
db = CreateConnection(response.FirstOrDefault());
idCie = (db.SYS_vwCie.Where(p => p.ClinicielWebName == code).FirstOrDefault()).IdCie;
}
catch (Exception e)
{
throw e;
}

}
else {
throw new FormatException();
}
}

private Cliniciel_WebRV_Entities CreateConnection(SYS_tbCustDBLocation data)
{

connectionString = *****

db = new Cliniciel_WebRV_Entities();

db.Database.Connection.ConnectionString = connectionString;

db.Database.Connection.Open();

return db;
}

private static void CreateInstance() {
instance = new DbConnection();
}

public static DbConnection GetInstance() {
lock (myLock)
{
if (instance == null)
{
CreateInstance();
}

}

return instance;
}

public String GetConnectionString()
{
return connectionString;
}

public Cliniciel_WebRV_Entities GetConnection()
{
return db;
}

public Int32 GetIdCie()
{
//hard code 1 but test
//return idCie;
return 1;
}

}
}

下面是我如何使用它的示例:

  //[CompanyCodeFilter]
public class HomeController : AppointementController
{
//public static Cliniciel_WebRV_Entities entityDB = DbConnection.GetConnection();

public HomeController()
{
base.Refresh();
}

public JsonResult GetConsultationDescription(Int32 idService)
{
//base.Refresh();
entityDB.Set<SYS_vwService>().AsNoTracking();
var motifDescription = entityDB.SYS_vwService.Where(s => s.IDLang == cultureName && s.IdService == idService && s.IdCie == idCie).FirstOrDefault();
var base64 = Convert.ToBase64String(motifDescription.ServiceImage);
var imgSrc = String.Format("data:image/gif;base64,{0}", base64);
var imageDecode = imgSrc;
if (base64 == "AA==")
{
imageDecode = "";
}
var result = new { motifDescription, imageDecode };


return Json(result, JsonRequestBehavior.AllowGet);
}
}

这里 base.refresh() 调用这个:

using System;
using System.Linq;
using WebRV.Filters;
using WebRV.Localization;
using WebRV.Models.Entities;
using WebRV.RouteDb;

namespace WebRV.Controllers
{
//[CompanyCodeFilter]
public class AppointementController : BaseController
{
protected Cliniciel_WebRV_Entities entityDB;
protected Int32 idCie;
protected String cultureName;

//public AppointementController() {
// Refresh();
//}

//Permet de bien vérifier quel DB utilisé, quel idCie et quel cultureName.
protected void Refresh() {
entityDB = DbConnection.GetInstance().GetConnection();
idCie= DbConnection.GetInstance().GetIdCie();
cultureName = CultureLocalization.GetCulture();
//cultureName = "en-ca";
}

}
}

如果有人可以帮助我正确实例化连接,将不胜感激,谢谢

最佳答案

我认为您需要更好地了解数据库上下文的工作原理。

它是许多设计模式的组合,但在基本层面上,它本质上是一个工作单元,用于跟踪代表数据的对象的变化。因此,它并不意味着用作始终保持打开状态的连接,您可以来回切换,尽管您可以在一定程度上这样使用它。

从您的代码来看,您似乎是在 ASP.NET MVC 应用程序中使用它。由于应用程序的性质,您可以执行以下两项操作之一:

  • 您可以在需要时创建数据库上下文,或者
  • 您可以创建数据库上下文作为 Controller 的属性

最后,它们在某种程度上相当于同一件事。我个人建议您在需要使用上下文时创建一个实例,并确保正确处理它。然后,您可以有一个基 Controller 类,它公开一个 CreateConnetion() 方法,为您的上下文创建一个实例,有点像您已经拥有的 Cliniciel_WebRV_Entities CreateConnection() 方法,除了您不需要显式打开连接,并且如果您添加分部类并为上下文实现一个分部类,则连接字符串可以作为构造函数参数传递。像这样:

public partial class Cliniciel_WebRV_Entities
{
public Cliniciel_WebRV_Entities(string nameOrConnectionString):base(nameOrConnectionString)
{

}
}

然后你可以像这样使用它:

private Cliniciel_WebRV_Entities CreateConnection()
{
//Code to figure out which db to connect to (based on the other connection. You should consider caching that too if it doesn't change very often)
var nameOrConnectionString = FigureOutConnection();
var db = new Cliniciel_WebRV_Entities(nameOrConnectionString);
return db;
}

请记住,上下文取决于元数据,因此请确保您的连接字符串反射(reflect)了这一点。

在您的代码中,您将像这样使用它:

public JsonResult GetConsultationDescription(Int32 idService)
{
using(var entityDB = CreateConnection())
{
var motifDescription = entityDB.SYS_vwService.Where(s => s.IDLang == cultureName && s.IdService == idService && s.IdCie == idCie).FirstOrDefault();
var base64 = Convert.ToBase64String(motifDescription.ServiceImage);
var imgSrc = String.Format("data:image/gif;base64,{0}", base64);
var imageDecode = imgSrc;
if (base64 == "AA==")
{
imageDecode = "";
}
var result = new { motifDescription, imageDecode };


return Json(result, JsonRequestBehavior.AllowGet);
}
}
}

另一件要记住并且让每个新手都头疼的事情是你不应该将实体(上下文中的对象)传递给模型中的 View 。这是因为一旦上下文被释放,具有导航属性的对象就会中断。有很多解决方法,但不推荐。而是将对象映射到模型。

顺便说一句,不要忘记在修改实体后调用SaveChanges() 方法,否则数据库将不会随着更改而更新。

关于c# Entity Framework 什么时候应该使用新的 dbContext?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41347176/

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