实体框架和存储库模式问题

时间:2009-09-26 14:28:04

标签: entity-framework repository-pattern

我使用通用存储库模式和方法:

    private ObjectQuery<T> ObjectQueryList()
    {
        var list = CamelTrapEntities.CreateQuery<T>(EntitySetName);
        return list;
    }

private ObjectQuery<T> ObjectQueryList() { var list = CamelTrapEntities.CreateQuery<T>(EntitySetName); return list; }

    public IQueryable<T> List()
    {
        return ObjectQueryList();
    }

Metod List()返回IQueryable&lt; T&gt;,因为IQueryable&lt; T&gt;很容易嘲笑。我也有扩展方法:

public IQueryable<T> List() { return ObjectQueryList(); }

此方法在存储库外部使用,以获取已加载导航属性的实体列表,例如:List.Include(“CreatedBy”)。问题是它不起作用。所有包含都被忽略。当我将List()方法更改为

    public static IQueryable<T> Include<T>(this IQueryable<T> obj, string path)
    {
        if (obj is ObjectQuery<T>)
            (obj as ObjectQuery<T>).Include(path);

        return obj;
    }

public static IQueryable<T> Include<T>(this IQueryable<T> obj, string path) { if (obj is ObjectQuery<T>) (obj as ObjectQuery<T>).Include(path); return obj; }

一切正常。

如何实现存储库模式以便能够执行更复杂的查询?

3 个答案:

答案 0 :(得分:6)

Reflector给了我一个答案:

public ObjectQuery<T> Include(string path)
{
    EntityUtil.CheckStringArgument(path, "path");
    return new ObjectQuery<T>(base.QueryState.Include<T>((ObjectQuery<T>) this, path));
}

public ObjectQuery<T> Include(string path) { EntityUtil.CheckStringArgument(path, "path"); return new ObjectQuery<T>(base.QueryState.Include<T>((ObjectQuery<T>) this, path)); }

Include返回新的ObjectQuery对象,我的Include函数返回旧对象。改为

public static IQueryable<T> Include<T>(this IQueryable<T> obj, string path)
{
    if (obj is ObjectQuery<T>)
        return (obj as ObjectQuery<T>).Include(path);

    return obj;
}

解决了这个问题。几个小时的丢失,我更讨厌实体框架:)

这让我也意识到我应该使用Include参数创建另一个List函数,并且不允许包含外部存储库。

答案 1 :(得分:1)

Here是我见过的最全面的Repository模式实现。我不能肯定地说它是否会允许你做Include(),但是如果我正确地阅读了它的实现,那就应该。

答案 2 :(得分:1)

使用EntityFramework 4.1,DbExtensions(System.Data.Entity.DbExtensions)可以解决此问题,并为.Include([string path])本地添加.Include([property expression])IQueryable<T>

确保使用您的存储库的项目引用EntityFramework,并且与任何扩展方法一样,在类文件中指定using System.Data.Entity;以获取对这些扩展的访问权。