【问题标题】:Error in generic repository method for Entity Framework实体框架的通用存储库方法中的错误
【发布时间】:2010-07-14 23:13:41
【问题描述】:

我正在尝试创建一个通用方法以在我的存储库的基类中使用,但我遇到了问题。方法是这样的……

        public virtual T First(System.Linq.Expressions.Expression<Func<T, bool>> where, List<string> properties)
    {
        IQueryable<T> query = null;
        if (where != null)
        {
            query = _context.CreateQuery<T>(String.Format("[{0}]", typeof(T).Name.ToString())).Where(where);
        }
        else
        {
            query = _context.CreateQuery<T>(String.Format("[{0}]", typeof(T).Name.ToString()));
        }

        foreach (string s in properties)
        {
            query = query.Include(s);
        }

        T _result = (T)query.First();

        return _result;
    }

当我运行代码时,它给了我这个错误:

“公司”无法在 当前范围或上下文。制作 确保所有引用的变量都是 在范围内,所需的模式是 加载,并且命名空间是 正确引用。差点逃脱 标识符,第 1 行,第 1 列。

我知道为什么会这样,只是不知道如何解决。我认为这样做是因为我的 ObjectContext 不知道对象“Company”,但它确实知道“Companies”。有关如何解决此问题的任何想法?

错误发生在这一行:

T _result = (T)query.First();

谢谢!

【问题讨论】:

  • 通常实体集名称是复数的,这就是上下文知道公司的原因。您使用的是哪个版本的 EF?
  • 我使用的是版本 4。是的,我猜这就是它无法正常工作的原因......但是有没有办法让它工作?
  • 使用FirstOrDefault而不是First,以防查询返回无结果。

标签: c# .net entity-framework


【解决方案1】:

Dan,获取实体集名称,如下所示:

string entitySetName = context.MetadataWorkspace
                        .GetEntityContainer(context.DefaultContainerName, DataSpace.CSpace)
                        .BaseEntitySets.Where(bes => bes.ElementType.Name == typeof(T).Name).First().Name;

string name = String.Format("{0}.{1}", context.DefaultContainerName, entitySetName);

query = context.CreateQuery<T>(name).Where(where);

这样做将解析查询的正确复数名称。

不过,使用 Yury 的方法是最好的选择。

编辑顺便说一句,如果查询没有返回任何实体,你应该返回FirstOrDefault() 而不是First()(它会抛出一个InvalidOperationException)。

【讨论】:

  • 更改为 FirstOrDefault()。感谢您的帮助!
【解决方案2】:

尝试使用

 query = _context.CreateObjectSet<T>().Where(where);

而不是

 query = _context.CreateQuery<T>(String.Format("[{0}]", typeof(T).Name.ToString())).Where(where);

【讨论】:

  • 这行得通。谢谢尤里!现在您或其他人能解释一下为什么会这样吗?
  • 不客气。好吧,为什么这个工作。 IObjectSet&lt;T&gt;ObjectSet&lt;T&gt; 的引入是 efv4 的改进之一。在以前的版本中,创建通用存储库很棘手,因为您必须知道您正在使用的实体类型的实体集的名称。这是Repository&lt;T&gt;实现的一个很好的例子,除了一件事:不要将Func&lt;T,bool&gt;作为选择器使用Expression&lt;Func&lt;T, bool&gt;&gt;,就像你已经做的那样:devtalk.dk/2009/06/09/…
猜你喜欢
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多