c# - Entity Framework ,存储库模式

标签 c# asp.net-mvc-3 entity-framework-4 repository-pattern

我正在尝试使用 Entity Framework - 存储库模式。 (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();
    }
}

这是测试 Controller ,

[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 -存储库模式。但大多数事情都非常复杂。所以我想让它像上面一样简单。

请多多指教~

谢谢!

[编辑]

我试试这个,

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相反。

特别是关于 SingleOrDefault 行为,MSDN 解释(强调):

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;
  }

更新:
如果您尝试我上面演示的存储库测试,您将需要进行一些重构。它不适用于您类(class)的当前状态。这将是您需要发布的另一个问题。上面的代码片段只是您的查询可能的一个例子。正如@Florim Maxhuni 所建议的那样,依赖注入(inject) (DI) 确实是可行的方法……仅取决于您的要求和时间限制。如果您的 DbContext 有问题,那将是一个不同的问题,应该在新线程中发布。 :)

关于c# - Entity Framework ,存储库模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11484757/

相关文章:

c# - 漏洞? System.ArgumentException : 'unable to figure out route for:

c# - 参数超出范围 - 卡片洗牌

c# - 无法将文本从一种编码解码为另一种编码

asp.net-mvc-3 - MVC3.0中的复选框列表

c# - 将 LINQ .Distinct() 与 DateTime 一起使用 - 仅选择日期的第一个实例

c# - Lambda 函数的主体用括号括起来?

asp.net-mvc-3 - 从属性抛出时如何捕获 Controller 中的错误?

asp.net-mvc-3 - ASP.NET MVC 3 不显眼的验证和单选按钮

entity-framework - Entity Framework 4 : which approach is the best

entity-framework-4 - Entity Framework 4.3.1 代码优先 : database created but tables are not