重构实例化数据上下文的 LINQ TO SQL 自定义属性
我正在开发一个现有的 ASP.NET MVC 应用程序,该应用程序一开始规模很小,但随着时间的推移不断发展,需要良好的重新架构和重构。
我正在努力解决的一件事是,我们已经获得了 L2S 实体的部分类,因此我们可以添加一些额外的属性,但这些属性会创建一个新的数据上下文并在数据库中查询数据的子集。这相当于在 SQL 中执行以下操作,这不是一个很好的方法来编写这个与连接相反的查询:
SELECT tbl1.stuff,
(SELECT nestedValue FROM tbl2 WHERE tbl2.Foo = tbl1.Bar),
tbl1.moreStuff
FROM tbl1
所以简而言之,这是我们在一些部分实体类中得到的:
public partial class Ticket {
public StatusUpdate LastStatusUpdate
{
get
{
//this static method call returns a new DataContext but needs to be refactored
var ctx = OurDataContext.GetContext();
var su = Compiled_Query_GetLastUpdate(ctx, this.TicketId);
return su;
}
}
}
我们有一些创建编译查询的函数,但问题是我们还在 DataContext 中定义了一些 DataLoadOptions,并且因为我们实例化了一个新的数据上下文来获取这些嵌套属性,所以我们得到一个异常
“跨 DataContext 的编译查询 使用不同的 LoadOptions 则不会 支持”
。第一个 DataContext 来自我们通过重构实现的 DataContextFactory,但第二个 DataContext 只是挂在实体属性 getter 上。
我们在重构过程中实现存储库模式,因此我们必须< /strong> 停止执行上述操作。有人知道解决此问题的好方法吗?
编辑:我正在添加我们在重构过程中创建的 DataContextFactory 的代码,请注意,在上面的代码中我们有一个 GetContext。 Linq DataContext 类中的 () 静态方法,该方法更新数据上下文,并且不使用下面的 DataContextFactory:
public class DataContextFactory<T> : IDataContextFactory where T : System.Data.Linq.DataContext
{
public DataContextFactory()
{
_context = Activator.CreateInstance<T>();
}
public DataContextFactory(T context)
{
_context = context;
}
private System.Data.Linq.DataContext _context;
public System.Data.Linq.DataContext Context
{
get
{
return _context;
}
}
public void SaveAll()
{
Context.SubmitChanges();
}
public bool IsContextDirty
{
get
{
return Context != null && (Context.GetChangeSet().Deletes.Count > 0 ||
Context.GetChangeSet().Inserts.Count > 0 ||
Context.GetChangeSet().Updates.Count > 0);
}
}
}
I am working on an existing ASP.NET MVC app that started small and has grown with time to require a good re-architecture and refactoring.
One thing that I am struggling with is that we've got partial classes of the L2S entities so we could add some extra properties, but these props create a new data context and query the DB for a subset of data. This would be the equivalent to doing the following in SQL, which is not a very good way to write this query as oppsed to joins:
SELECT tbl1.stuff,
(SELECT nestedValue FROM tbl2 WHERE tbl2.Foo = tbl1.Bar),
tbl1.moreStuff
FROM tbl1
so in short here's what we've got in some of our partial entity classes:
public partial class Ticket {
public StatusUpdate LastStatusUpdate
{
get
{
//this static method call returns a new DataContext but needs to be refactored
var ctx = OurDataContext.GetContext();
var su = Compiled_Query_GetLastUpdate(ctx, this.TicketId);
return su;
}
}
}
We've got some functions that create a compiled query, but the issue is that we also have some DataLoadOptions defined in the DataContext, and because we instantiate a new datacontext for getting these nested property, we get an exception
"Compiled Queries across DataContexts
with different LoadOptions not
supported"
. The first DataContext is coming from a DataContextFactory that we implemented with the refactorings, but this second one is just hanging off the entity property getter.
We're implementing the Repository pattern in the refactoring process, so we must stop doing stuff like the above. Does anyone know of a good way to address this issue?
EDIT: I am adding the code for the DataContextFactory that we created during our refactoring efforts. Note that in the code above we have a GetContext() static method in the Linq DataContext class, which news up a datacontext, and is not using the DataContextFactory below:
public class DataContextFactory<T> : IDataContextFactory where T : System.Data.Linq.DataContext
{
public DataContextFactory()
{
_context = Activator.CreateInstance<T>();
}
public DataContextFactory(T context)
{
_context = context;
}
private System.Data.Linq.DataContext _context;
public System.Data.Linq.DataContext Context
{
get
{
return _context;
}
}
public void SaveAll()
{
Context.SubmitChanges();
}
public bool IsContextDirty
{
get
{
return Context != null && (Context.GetChangeSet().Deletes.Count > 0 ||
Context.GetChangeSet().Inserts.Count > 0 ||
Context.GetChangeSet().Updates.Count > 0);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不要在调用方法时创建 DataContext,而是将其存储在 HttpContext.Current.Items 中。
这将实现与将其存储在私有字段中相同的效果,因为它对于请求来说是唯一的。
Instead of creating the DataContext whenever the method is called, store it in
HttpContext.Current.Items
.This will achieve the same effect as storing it in a private field, as it will be unique to the request.