Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework 使用EF实现通用存储库_Entity Framework_Entity Framework 4_Repository_Repository Pattern - Fatal编程技术网

Entity framework 使用EF实现通用存储库

Entity framework 使用EF实现通用存储库,entity-framework,entity-framework-4,repository,repository-pattern,Entity Framework,Entity Framework 4,Repository,Repository Pattern,对于一个简单的存储库 public interface ISimpleRepository<T> { IApplicationState AppState { get; set; } void Add(T instance); void Delete(T instance); void Delete(Guid rowGuid); IQueryable<T> GetAll(); T Load(Guid rowGuid);

对于一个简单的存储库

public interface ISimpleRepository<T>
{
    IApplicationState AppState { get; set; }
    void Add(T instance);
    void Delete(T instance);
    void Delete(Guid rowGuid);
    IQueryable<T> GetAll();
    T Load(Guid rowGuid);
    void SaveChanges();
    void Update(T instance);
}
现在假设我的存储库实现类如下所示:

    public Product Load(Guid rowid)
    {
        return (from c in _ctx.Products where c.id == rowid select c).FirstOrDefault();
    }
public class EntityFrameworkProductsProvider : IRepository<Product> ...
public class EntityFrameworkDefaultProvider<T> : IRepository<T> ...
public class EntityFrameworkDefaultProvider<T> : IRepository<T> where T:class
{
    public T Load(Guid rowId)
    {
        return _context.Set<T>().Find(rowId);
    }
}
如果我有几十个或数百个这样的小而简单的实体,当CRUD使用相同的方法实现时,它们都会使用相同的行为,会怎么样?我当然不想去创建一个类来为它们中的每一个实现IRepository

我想要这样的东西:

    public Product Load(Guid rowid)
    {
        return (from c in _ctx.Products where c.id == rowid select c).FirstOrDefault();
    }
public class EntityFrameworkProductsProvider : IRepository<Product> ...
public class EntityFrameworkDefaultProvider<T> : IRepository<T> ...
public class EntityFrameworkDefaultProvider<T> : IRepository<T> where T:class
{
    public T Load(Guid rowId)
    {
        return _context.Set<T>().Find(rowId);
    }
}
但是我不知道如何实现LINQ Select表达式,因为我当然不能从e in_ctx.t中写入,其中e。。。还是我

我还没有遇到这种情况,因为到目前为止,我只有非常特定的实体具有自定义存储库实现。

您可以编写_ctx.Set,而不是编写_ctx.Products。这解决了您需要在存储库中添加一个通用约束(其中T:class)的一半问题

然后,如果rowid是对象的键,则可以使用_ctx.Set.Findrowid而不是LINQ查询来按Id检索

或者,您可以创建一个基接口IHaveId或一个BaseEntity类,无论您喜欢哪个类,它都具有Id属性,然后将其添加为T上的通用约束,这样您就可以在查询中使用它。

您可以编写_ctx.Set,而不是编写_ctx.Products。这解决了您需要在存储库中添加一个通用约束(其中T:class)的一半问题

然后,如果rowid是对象的键,则可以使用_ctx.Set.Findrowid而不是LINQ查询来按Id检索


或者,您可以创建一个基接口IHaveId或一个BaseEntity类,无论您喜欢哪个类,它都具有Id属性,然后将其添加为T上的通用约束,这样您就可以在查询中使用它了。

我知道这在EF4.1和DbContext API中是可能的,其中,您在上下文中有一个Set方法,该方法获取与类型T对应的实体集。这样,您的存储库可以如下所示:

    public Product Load(Guid rowid)
    {
        return (from c in _ctx.Products where c.id == rowid select c).FirstOrDefault();
    }
public class EntityFrameworkProductsProvider : IRepository<Product> ...
public class EntityFrameworkDefaultProvider<T> : IRepository<T> ...
public class EntityFrameworkDefaultProvider<T> : IRepository<T> where T:class
{
    public T Load(Guid rowId)
    {
        return _context.Set<T>().Find(rowId);
    }
}
要获取所需的实体,而不是使用来自。。。在里面在我看来,这更清楚:


希望这有助于

我知道,在EF4.1中,使用DbContext API可以实现这一点,在该API中,上下文上有一个Set方法,可以获取与T类型对应的实体集。这样,您的存储库可以如下所示:

    public Product Load(Guid rowid)
    {
        return (from c in _ctx.Products where c.id == rowid select c).FirstOrDefault();
    }
public class EntityFrameworkProductsProvider : IRepository<Product> ...
public class EntityFrameworkDefaultProvider<T> : IRepository<T> ...
public class EntityFrameworkDefaultProvider<T> : IRepository<T> where T:class
{
    public T Load(Guid rowId)
    {
        return _context.Set<T>().Find(rowId);
    }
}
要获取所需的实体,而不是使用来自。。。在里面在我看来,这更清楚:


希望这对您有所帮助,因为您已将问题标记为,并且我假设您正在使用ObjectContext API。ObjectContext提供方法CreateObjectSet,该方法相当于DbContext上的Set

这个问题实际上与以下两个问题重复:


因为您将问题标记为,我假设您使用的是ObjectContext API。ObjectContext提供方法CreateObjectSet,该方法相当于DbContext上的Set

这个问题实际上与以下两个问题重复:


如果您使用的是EF 4.1,请参见此处的示例通用存储库:

如果您使用的是EF 4.1,请参见此处的示例通用存储库:

看看这篇文章:。看看这篇文章:。@Diego Mijelshon:如果id包含的列超过1列怎么办?@Naor:它们不符合他的界面。无论如何,这是一种不好的做法,但是Find支持将对象[]作为参数传递,因此理论上他也可以添加它。@Diego Mijelshon:但是Find方法如何知道如何将每个对象映射到每个键?我问过Ladislav Mrnka,@Naor:按照HasKey方法定义它们的顺序。请参见@Diego Mijelshon:HashKey在哪里定义?@Diego Mijelshon:如果id包含的列超过1列,该怎么办?@Naor:根据他的接口,它们不存在。无论如何,这是一种不好的做法,但是Find支持将对象[]作为参数传递,因此理论上他也可以添加它。@Diego Mijelshon:但是Find方法如何知道如何将每个对象映射到每个键?我问过Ladislav Mrnka,@Naor:按照HasKey方法定义它们的顺序。参见@Diego Mijelshon:HashKey在哪里定义?