새 DbContext ()는 언제 만들어야합니까?
나는 현재 다음 DbContext
과 비슷한 것을 사용하고 있습니다 .
namespace Models
{
public class ContextDB: DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<UserRole> UserRoles { get; set; }
public ContextDB()
{
}
}
}
그런 다음 데이터베이스에 액세스해야하는 모든 컨트롤러 의 맨 위에 다음 줄을 사용 하고 있습니다. Im은 또한 사용자와 관련된 모든 메서드를 포함하는 UserRepository 클래스에서 사용합니다 (예 : 활성 사용자 가져 오기, 그가 가지고있는 역할 확인 등).
ContextDB _db = new ContextDB();
이것을 생각하면 .. 한 방문자가 여러 DbContext를 활성화 할 수있는 경우가 있습니다. 즉. 그가 UserRepository를 사용하는 컨트롤러를 방문한다면 .. 이것은 최선의 아이디어가 아닐 수 있으며 그것에 대해 몇 가지 질문이 있습니다
- 새 DbContext를 언제 만들어야하나요? / 내가 전달하는 하나의 전역 컨텍스트가 있어야하나요?
- 모든 위치에서 재사용 할 수있는 하나의 글로벌 컨텍스트를 가질 수 있습니까?
- 이로 인해 성능 저하가 발생합니까?
- 다른 사람들은 어떻게 이것을하고 있습니까?
DataBase
파생 컨트롤러가 액세스 할 수 있는 속성을 노출하는 기본 컨트롤러를 사용합니다 .
public abstract class BaseController : Controller
{
public BaseController()
{
Database = new DatabaseContext();
}
protected DatabaseContext Database { get; set; }
protected override void Dispose(bool disposing)
{
Database.Dispose();
base.Dispose(disposing);
}
}
내 응용 프로그램의 모든 컨트롤러는 다음에서 파생되며 다음 BaseController
과 같이 사용됩니다.
public class UserController : BaseController
{
[HttpGet]
public ActionResult Index()
{
return View(Database.Users.OrderBy(p => p.Name).ToList());
}
}
이제 귀하의 질문에 답하십시오.
새 DbContext를 언제 만들어야하나요? / 내가 전달하는 하나의 전역 컨텍스트가 있어야하나요?
컨텍스트는 요청별로 생성되어야합니다. 컨텍스트를 만들고 필요한 작업을 수행 한 다음 제거하십시오. 기본 클래스 솔루션을 사용하면 컨텍스트 사용에 대해서만 걱정하면됩니다.
글로벌 컨텍스트를 시도하지 마십시오 (웹 애플리케이션의 작동 방식이 아님).
모든 위치에서 재사용 할 수있는 하나의 글로벌 컨텍스트를 가질 수 있습니까?
아니요, 컨텍스트를 유지하면 모든 업데이트, 추가, 삭제 등을 추적 할 수 있으며 이로 인해 애플리케이션 속도가 느려지고 애플리케이션에 매우 미묘한 버그가 나타날 수도 있습니다.
저장소 또는 컨텍스트를 컨트롤러에 노출하도록 선택해야 하지만 둘다는 아닙니다. 동일한 메서드에서 두 컨텍스트에 액세스하는 것은 둘 다 애플리케이션의 현재 상태에 대해 서로 다른 아이디어를 가지고있는 경우 버그로 이어질 것입니다.
개인적으로 나는 내가 DbContext
본 대부분의 저장소 예제가 DbContext
어쨌든 얇은 래퍼로 끝나는 것처럼 직접 노출하는 것을 선호 합니다.
이로 인해 성능 저하가 발생합니까?
a를 처음 DbContext
만들 때는 비용이 많이 들지만 일단 이렇게되면 많은 정보가 캐시되어 후속 인스턴스화가 훨씬 빨라집니다. 데이터베이스에 액세스해야 할 때마다 인스턴스화하는 것보다 컨텍스트를 유지하여 성능 문제를 볼 가능성이 더 큽니다.
다른 사람들은 어떻게 이것을하고 있습니까?
때에 따라 다르지.
어떤 사람들은 생성 될 때 자신의 컨텍스트의 구체적인 인스턴스를 컨트롤러에 전달하기 위해 종속성 주입 프레임 워크를 사용하는 것을 선호합니다. 두 옵션 모두 괜찮습니다. Mine은 사용중인 특정 데이터베이스가 변경되지 않을 것이라는 것을 알고있는 소규모 애플리케이션에 더 적합합니다.
some may argue that you can't know this and that is why the dependency injection method is better as it makes your application more resilient to change. My opinion on this is that it probably won't change (SQL server & Entity Framework are hardly obscure) and that my time is best spent writing the code that is specific to my application.
I try to answer out of my own experience.
1. When should I make a new DbContext / should I have one global context that I pass around?
The Context should be injected by the dependency-injection and should not be instantiated by yourself. Best-Practice is to have it created as a scoped service by the dependency-injection. (See my answer to Question 4)
Please also consider using a proper layered application structure like Controller > BusinessLogic > Repository. In this case it would not be the case that your controller receives the db-context but the repository instead. Getting injected / instantiating a db-context in a controller tells me that your application architecture mixes many responsibilities in one place, which - under any circumstances - I cannot recommend.
2. Can i have one global Context that I reuse in all places?
Yes you can have but the question should be "Should I have..." -> NO. The Context is meant to be used per request to change your repository and then its away again.
3. Does this cause a performance hit?
Yes it does because the DBContext is simply not made for being global. It stores all the data that has been entered or queried into it until it is destroyed. That means a global context will get larger and larger, operations on it will get slower and slower until you will get an out of memory exceptions or you die of age because it all slowed to a crawl.
You will also get exceptions and many errors when multiple threads access the same context at once.
4. How is everyone else doing this?
DBContext injected through dependency-injection by a factory; scoped:
services.AddDbContext<UserDbContext>(o => o.UseSqlServer(this.settings.DatabaseOptions.UserDBConnectionString));
I hope my answers where of help.
Right now I am trying this approach, which avoids instantiating the context when you call actions that don't use it.
public abstract class BaseController : Controller
{
public BaseController() { }
private DatabaseContext _database;
protected DatabaseContext Database
{
get
{
if (_database == null)
_database = new DatabaseContext();
return _database;
}
}
protected override void Dispose(bool disposing)
{
if (_database != null)
_database.Dispose();
base.Dispose(disposing);
}
}
This is obviously an older question but if your using DI you can do something like this and scope all your objects for the lifetime of the request
public class UnitOfWorkAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var context = IoC.CurrentNestedContainer.GetInstance<DatabaseContext>();
context.BeginTransaction();
}
public override void OnActionExecuted(HttpActionExecutedContext actionContext)
{
var context = IoC.CurrentNestedContainer.GetInstance<DatabaseContext>();
context.CloseTransaction(actionContext.Exception);
}
}
참고URL : https://stackoverflow.com/questions/13551100/when-should-i-create-a-new-dbcontext
'IT Share you' 카테고리의 다른 글
Apache RewriteRule 지시문에서 환경 변수를 설정할 때 변수 이름 앞에 "REDIRECT_"가 붙는 이유는 무엇입니까? (0) | 2020.11.08 |
---|---|
동시 JUnit 테스트 (0) | 2020.11.08 |
java.net.SocketTimeoutException 가져 오기 : Android에서 연결 시간이 초과되었습니다. (0) | 2020.11.08 |
Ruby에서 동적 메서드 호출 (0) | 2020.11.08 |
C # 엔티티 프레임 워크 : 저장소 클래스 내에서 DBContext 클래스의 올바른 사용 (0) | 2020.11.08 |