1

そのため、タイトルの用語が正しいかどうかはわかりませんが、やろうとしていることを説明できるはずです。

実際のすべての Repository クラスが継承する "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;
    }
}

今、私がやろうとしているのは、エンティティの "Name" プロパティを渡すことができる GetByName メソッドを追加して、それを返すことです。

私はもう試した

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

しかし、それは「TEntityには名前の定義が含まれていません」などと言ってNameに下線を引いています。これは理にかなっています。

個々のリポジトリでこれを簡単に行うことができますが、ジェネリックリポジトリでそれを行う方法があるかどうか疑問に思っていました.

どんな助けでも大歓迎です!

4

3 に答える 3

2

If all your entities types have Name property, then you can extend TEntity inteface with Name property.

Otherwise, you can use SqlQuery() method of DbSet with string query as a parameter.

于 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.
}

エンティティの 1 つが Name プロパティを使用しない場合、いくつかのオプションがあります。エンティティ内の適切なプロパティ名を Name に変更し、それを元の storagemodel 名に適切にマップできます。または、元の汎用リポジトリを継承することもできます。

NamedRepository:

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 に答える