代码之家  ›  专栏  ›  技术社区  ›  Chris Klepeis

ASP.NET实体框架存储库和LINQ

  •  3
  • Chris Klepeis  · 技术社区  · 16 年前

    我的场景:

    这是一个通过C编程的ASP.NET 4.0 Web应用程序#

    我实现了一个存储库模式。我的储物柜都是一样的 ObjectContext ,存储在httpContext.items中。每个存储库创建一个新的 ObjectSet 类型为E。以下是我的存储库中的一些代码:

    public class Repository<E> : IRepository<E>, IDisposable
        where E : class
    {
        private DataModelContainer _context = ContextHelper<DataModelContainer>.GetCurrentContext();
        private IObjectSet<E> _objectSet;
        private IObjectSet<E> objectSet
        {
            get
            {
                if (_objectSet == null)
                {
                    _objectSet = this._context.CreateObjectSet<E>();
                }
                return _objectSet;
            }
        }
    
        public IQueryable<E> GetQuery()
        {
            return objectSet;
        }
    

    假设我有2个存储库,1个用于州,1个用于国家,并且希望对这两者创建一个LINQ查询。注意,我在实体框架中使用了POCO类。州和国家是这些POCO类中的两个。

    Repository stateRepo = new Repository<State>();
    Repository countryRepo = new Repository<Country>();
    
    IEnumerable<State> states = (from s in _stateRepo.GetQuery()
                                 join c in _countryRepo.GetQuery() on s.countryID equals c.countryID
                                 select s).ToList();
    Debug.WriteLine(states.First().Country.country)
    

    基本上,我想检索州和相关国家实体。查询只返回状态数据…我得到一个空参数异常 Debug.WriteLine

    Lazyloading在我的.edmx中被禁用…我就是这么想的。

    2 回复  |  直到 16 年前
        1
  •  2
  •   Julien Lebosquain    16 年前

    您正在进行一个没有从中检索任何内容的联接。您的问题有多种解决方案:

    • 使用 Include 要加载从属实体,请执行以下操作: from s in ((ObjectSet<State>) _stateRepo.GetQuery).Include("Country") . 这种方法的问题在于,您应该公开 ObjectSet 直接而不是作为 IQueryable 如果你想避免铸造。
    • 使用 context.LoadProperty(states.First(), s => s.Country) 从数据库中显式加载给定状态的国家。
    • 在查询中选择两个实体: from s in ... join c ... select new { s, c } . 您将无法直接访问州的 Country 属性,但它属于匿名类型。
    • 启用延迟加载。
        2
  •  1
  •   Adrian Grigore    16 年前

    您的存储库实现与我的非常相似,特别是您存储ObjectContext的方式。它对我来说很好,所以我不认为这是概念问题。

    尝试使用静态的ObjectContext(没有包装器),看看是否能解决问题。可能在ContextHelper中有一个错误,它会导致您的上下文被释放并重新创建。