1

所以我不确定标题中的术语是否正确,但我应该能够描述我正在尝试做的事情。

我有一个“GenericRepository”类,我所有的实际存储库类都继承自它,它包含几个通用方法。该类的代码如下

public class GenericRepository<TEntity> where TEntity : class
{
    internal ReportsDirectoryEntities context;
    internal DbSet<TEntity> dbSet;

    public GenericRepository(ReportsDirectoryEntities context)
    {
        this.context = context;
        this.dbSet = context.Set<TEntity>();
    }

    /////////////////////////////////////////////////////////////////////

    public virtual IEnumerable<TEntity> GetAll()
    {
        return dbSet.ToList();
    }
    public virtual TEntity GetByID(int id)
    {
        return dbSet.Find(id);
    }
    public virtual void Insert(TEntity entity)
    {
        dbSet.Add(entity);
    }
    public virtual void Delete(object id)
    {
        TEntity entityToDelete = dbSet.Find(id);
        Delete(entityToDelete);
    }
    public virtual void Delete(TEntity entityToDelete)
    {
        if (context.Entry(entityToDelete).State == System.Data.EntityState.Detached)
        {
            dbSet.Attach(entityToDelete);
        }
        dbSet.Remove(entityToDelete);
    }
    public virtual void Update(TEntity entityToUpdate)
    {
        dbSet.Attach(entityToUpdate);
        context.Entry(entityToUpdate).State = System.Data.EntityState.Modified;
    }
}

现在所有这些都很好,我现在要做的是添加一个 GetByName 方法,我可以在其中传递实体的“名称”属性并返回它。

我试过了

    public virtual TEntity GetByName(string name)
    {
        return (from e in context.Set<TEntity>()
                where e.Name == name
                select e).SingleOrDefault();
    } 

但这强调了 Name 说“TEntity 不包含名称的定义”等等,这是有道理的。

我可以在单个存储库中轻松地做到这一点,但想知道是否有一种方法可以在通用存储库中做到这一点。

任何帮助是极大的赞赏!

4

3 回答 3

2

如果您的所有实体类型都有Name属性,那么您可以TEntity使用Name属性扩展接口。

否则,您可以使用带有字符串查询的SqlQuery()方法DbSet作为参数。

于 2012-12-11T19:16:01.017 回答
1

为了清楚地做到这一点,TEntity需要将其限制为具有 Name 属性的类型(或接口)。否则,您正在使用反射(或dynamic访问 Name 属性),它允许直到运行时才被捕获的错误。

于 2012-12-11T19:11:46.467 回答
1

如果您的所有实体都使用 Name 作为属性,您只需创建一个接口并将其用作泛型类的约束。

界面:

public interface IStringName
{
    public string Name { get; set; }
}

实体:

public partial class MyEntity : IStringName
{
    public String Name { get; set; }
    // Additional properties here.
}

存储库:

public class GenericRepository<TEntity> where TEntity : class, IStringName
{
    // Your code here.
}

如果您的实体之一不使用 Name 属性,您有几个选择。您可以将实体中的适当属性名称更改为 Name,并将其适当地映射到原始存储模型名称。或者,您可以继承原始的通用存储库,例如。

命名存储库:

public class NamedRepository<TEntity> : GenericRepository<TEntity>
    where TEntity : class, IStringName
{
    public NamedRepository(ReportsDirectoryEntities context) : base(context)
    {
    }

    public virtual TEntity GetByName(string name)
    {
        return (from e in base.context.Set<TEntity>()
                where e.Name == name
                select e).SingleOrDefault();
    }
}

这种方法将允许您在实现新接口的实体上使用 NamedRepository,并为那些没有实现的实体使用原始 GenericRepository。

于 2014-03-21T00:30:44.383 回答