c#-实体框架,存储库模式
作者:互联网
我正在尝试使用Entity Framework-Repository Pattern. (Asp.net C#,EF4)
我为每个数据库表创建存储库.但是当我联接表时,会出现一个错误,说
“指定的LINQ表达式包含对与不同上下文关联的查询的引用.”
为了避免出现错误消息,我将所有内容都放在一个类中,如下所示:
public class WebOrderRepository
{
private DbEntities context = new DbEntities(); //Web.config <add name="DBEntities" connectionString=" ...
public IQueryable<WEBORDERHD> WebOrderHds
{
get { return context.WEBORDERHDs; }
}
public IQueryable<WEBORDERLN> WebOrderLns
{
get { return context.WEBORDERLNs; }
}
}
您能检查一下我的代码吗?
这是我的存储库类,
public class Repository : IDisposable
{
protected ShkAdsEntities context;
private bool _disposed;
public Repository()
{
context = new ShkAdsEntities();
}
public void Dispose() //If define this class as Static then, 'Dispose': cannot declare instance members in a static class
{
DisposeObject(true);
GC.SuppressFinalize(this);
}
~Repository()
{
DisposeObject(false);
}
private void DisposeObject(bool disposing)
{
if (_disposed)
{
return;
}
if(disposing){
if (context != null)
{
context.Dispose();
}
_disposed = true;
}
}
}
public class WebOrderHdRepository : Repository
{
public IQueryable<WEBORDERHD> WebOrderHds
{
get { return context.WEBORDERHDs; }
}
public void Create(WEBORDERHD obj)
{
}
public void Delete(WEBORDERHD ojb)
{
}
public void SubmitChanges()
{
context.SaveChanges();
}
}
public class WebOrderLnRepository : Repository
{
public IQueryable<WEBORDERLN> WebOrderLns
{
get { return context.WEBORDERLNs; }
}
public void Create(WEBORDERLN obj)
{
}
public void Delete(WEBORDERLN ojb)
{
}
public void SubmitChanges()
{
context.SaveChanges();
}
}
这是测试的控制器,
[HttpGet]
public ActionResult repositoryTest()
{
WebOrderHdRepository webOrderHdRepository = new WebOrderHdRepository();
WebOrderLnRepository webOrderLnRepository = new WebOrderLnRepository();
var result = (from x in webOrderHdRepository.WebOrderHds
join u in webOrderLnRepository.WebOrderLns on x.OrderNo equals u.OrderNo
select new {x.OrderNo}).SingleOrDefault();
return Content(result.OrderNo);
}
我尝试将上下文定义为静态,
protected static ShkAdsEntities context = null;
public Repository()
{
if (context == null)
{
context = new ShkAdsEntities();
}
}
然后,发生另一个错误,
Sequence contains more than one element
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: Sequence contains more than one element
Source Error:
Line 116: {
Line 117: WebOrderHdRepository webOrderHdRepository = new WebOrderHdRepository();
Line 118: WebOrderLnRepository webOrderLnRepository = new WebOrderLnRepository(); <== ERROR POINT
Line 119:
Line 120: var result = (from x in webOrderHdRepository.WebOrderHds
我在许多方面搜索Entity Framework-Repository模式.但是大多数事情都很复杂.所以我想像上面这样简单.
请指教我〜
谢谢!
[编辑]
我尝试这个
using(WebOrderHdRepository webOrderHdRepository = new WebOrderHdRepository())
using (WebOrderLnRepository webOrderLnRepository = new WebOrderLnRepository())
{
.
.
但是发生错误,
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ObjectDisposedException: The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
Source Error:
Line 114: {
Line 115: using(WebOrderHdRepository webOrderHdRepository = new WebOrderHdRepository())
Line 116: using (WebOrderLnRepository webOrderLnRepository = new WebOrderLnRepository())
Line 117: {
Line 118:
我认为它尝试处理两次,但是我不知道如何修复代码…
有人知道,请指教我〜
谢谢
解决方法:
您可以将异常追溯到以下语句:
var result = (from x in webOrderHdRepository.WebOrderHds
join u in webOrderLnRepository.WebOrderLns on x.OrderNo equals u.OrderNo
select new {x.OrderNo}).SingleOrDefault();
错误发生在SingleOrDefault
中-您的集合有多个结果.查看MSDN文档,确定是否应使用FirstOrDefault
.
MSDN专门针对SingleOrDefault行为进行了解释(强调):
Returns the only element of a sequence, or a default value if the
sequence is empty; this method throws an exception if there is more
than one element in the sequence.
关于您的DbContext,您应该能够拥有单独的存储库,只需确保每个存储库都使用相同的上下文对象即可.我猜(没有看到原始的实现),每个存储库都实例化了它自己的上下文对象.我看不到您当前的实现有什么特别的问题,尽管有些问题可能会提出以下建议(未经测试):
public ActionResult repositoryTest() {
ActionResult actionRes = default(ActionResult);
using (ShkAdsEntities context = new ShkAdsEntities())
using (WebOrderHdRepository webOrderHdRepository = new WebOrderHdRepository(context))
using (WebOrderLnRepository webOrderLnRepository = new WebOrderLnRepository(context)) {
var result = (from x in webOrderHdRepository.WebOrderHds
join u in webOrderLnRepository.WebOrderLns on x.OrderNo equals u.OrderNo
select new { x.OrderNo }).SingleOrDefault();
actionRes = Content(result.OrderNo);
}
return actionRes;
}
更新:
如果您确实尝试了上面演示的存储库测试,则需要进行一些重构.它不适用于您当前的类状态.这是您需要发布的另一个问题.上面的片段仅是查询内容的一个示例.正如@ Florim Maxhuni所建议的那样,依赖注入(DI)确实是可行的途径……仅取决于您的要求和时间限制.如果您的DbContext有问题,那将是另一个问题,应发布在新线程中.
标签:repository-pattern,entity-framework-4,c,asp-net-mvc-3 来源: https://codeday.me/bug/20191101/1980997.html