在EF模型和代码使用者之间使用存储库

时间:2012-03-31 19:34:46

标签: asp.net entity-framework repository repository-pattern mvp

我的数据库中有二进制数据,我必须在某些时候将其转换为位图。我在想是否适合使用存储库并在那里执行。我的使用者(表示层)将使用此存储库。例如:

// This is a class I created for modeling the item as is.
public class RealItem
{
    public string Name { get; set; }
    public Bitmap Image { get; set; }
}

public abstract class BaseRepository
{
    //using Unity (http://unity.codeplex.com) to inject the dependancy of entity context.
    [Dependency]
    public Context { get; set; }
}

public calss ItemRepository : BaseRepository
{
    public List<Items> Select()
    {
        IEnumerable<Items> items = from item in Context.Items select item;
        List<RealItem> lst = new List<RealItem>();
        foreach(itm in items)
        {
            MemoryStream stream = new MemoryStream(itm.Image);
            Bitmap image = (Bitmap)Image.FromStream(stream);
            RealItem ritem = new RealItem{ Name=item.Name, Image=image };
            lst.Add(ritem);
        }

        return lst;
    }
}

这是使用存储库模式的正确方法吗?我正在学习这种模式,我在网上看到很多使用存储库的例子,但是当我查看他们的源代码时...例如:

public IQueryable<object> Select
{
    return from q in base.Context.MyItems select q;
}

正如你所看到的那样,除了隐藏数据访问查询之外,几乎没有任何行为被他们的方法添加到系统中,所以我很困惑,也许存储库是别的东西而且我弄错了。最后应该有额外的好处吗?

更新,因为事实证明,如果在发送数据之前没有其他任何事情要做,你就不需要存储库,但是等等! LINQ查询没有抽象?这样客户端必须为我们提供查询语句,这可能有点不安全且难以验证,因此存储库也可能提供数据查询的抽象?如果这是真的那么拥有存储库始终是项目架构中的基本需求!! 然而这种抽象可以通过使用SQL存储过程来提供。如果两个选项都可用,那么选择是什么?

2 个答案:

答案 0 :(得分:4)

是的,这是正确的方法:存储库合同满足应用程序需求,处理应用程序对象。

您在大多数情况下看到的(糟糕)示例将任何存储库实现与IQueryable相关联,这可能会或可能不会被底层orm实现,毕竟它是一个实现细节。

IQueryable和IEnumerable之间的区别在处理远程数据时很重要,但这就是存储库首先做的事情:它隐藏了你正在处理可以远程存储的事实。对于应用程序,存储库只是一个本地对象集合。

<强>更新 存储库抽象了持久性访问,它使应用程序与特定的持久性实现分离,并将自身屏蔽为一个简单的集合。这意味着应用程序不知道Linq2Sql,Sql或所使用的RDBMS类型(如果有)。应用程序从repo发送/接收对象,而repo实际上持久存储或加载对象。该应用程序并不关心回购如何做到。

我认为存储库是一个非常有用的模式,我在每个项目中都使用它,正是因为它标记了应用程序(作为定义和处理问题和解决方案的地方)与数据存储/存储之间的边界。保存。

答案 1 :(得分:1)

您可以使存储库成为通用存储库,并且可以从中获取模式值。并确保您使用接口(IItemRepository)访问管理器层中的存储库,以便您可以使用新的存储库实现将您的存储库替换为另一种数据访问方法。 Here is an good exampl如何做到这一点。