Frage

Ich bin immer bereit, ein neues asp.net Web-Projekt zu starten, und ich werde LINQ-to-SQL. Ich habe ein wenig Arbeit getan meine Daten Layer-Setup bekommen einige Informationen mit fand ich von Mike Hadlow dass verwendet eine Schnittstelle und Generika ein Repository für jede Tabelle in der Datenbank zu erstellen. Ich dachte, das ein interessanter Ansatz, zuerst war. Aber jetzt denke ich, es könnte mehr Sinn machen, eine Basis-Repository-Klasse zu erstellen und erben von ihm eine TableNameRepository Klasse für die Tabellen erstellen ich zugreifen müssen.

Welcher Ansatz wird ich erlauben, Funktionalität spezifisch für eine Tabelle in einer sauberen prüfbaren Weise hinzufügen? Hier ist meine Repository Implementierung Referenz.

public class Repository<T> : IRepository<T> where T : class, new()
{
    protected IDataConnection _dcnf;

    public Repository()
    {
        _dcnf = new DataConnectionFactory() as IDataConnection;
    }

    // Constructor injection for dependency on DataContext 
    // to actually connect to a database
    public Repository(IDataConnection dc)
    {
        _dcnf = dc;
    }

    /// <summary>
    /// Return all instances of type T.
    /// </summary>
    /// <returns>IEnumerable<T></returns>
    public virtual IEnumerable<T> GetAll()
    {
        return GetTable;
    }

    public virtual T GetById(int id)
    {
        var itemParam = Expression.Parameter(typeof(T), "item");
        var whereExp = Expression.Lambda<Func<T, bool>>
            (
                Expression.Equal(
                    Expression.Property(itemParam, PrimaryKeyName),
                    Expression.Constant(id)
                ), new ParameterExpression[] { itemParam }
            );
        return _dcnf.Context.GetTable<T>().Where(whereExp).Single();
    }

    /// <summary>
    /// Return all instances of type T that match the expression exp.
    /// </summary>
    /// <param name="exp"></param>
    /// <returns>IEnumerable<T></returns>
    public virtual IEnumerable<T> FindByExp(Func<T, bool> exp)
    {
        return GetTable.Where<T>(exp);
    }

    /// <summary>See IRepository.</summary>
    /// <param name="exp"></param><returns></returns>
    public virtual T Single(Func<T, bool> exp)
    {
        return GetTable.Single(exp);
    }

    /// <summary>See IRepository.</summary>
    /// <param name="entity"></param>
    public virtual void MarkForDeletion(T entity)
    {
        _dcnf.Context.GetTable<T>().DeleteOnSubmit(entity);
    }

    /// <summary>
    /// Create a new instance of type T.
    /// </summary>
    /// <returns>T</returns>
    public virtual T Create()
    {
        //T entity = Activator.CreateInstance<T>();
        T entity = new T();
        GetTable.InsertOnSubmit(entity);
        return entity;
    }

    /// <summary>See IRepository.</summary>
    public virtual void SaveAll()
    {
        _dcnf.SaveAll();
    }

    #region Properties
    private string PrimaryKeyName
    {
        get { return TableMetadata.RowType.IdentityMembers[0].Name; }
    }

    private System.Data.Linq.Table<T> GetTable
    {
        get { return _dcnf.Context.GetTable<T>(); }
    }

    private System.Data.Linq.Mapping.MetaTable TableMetadata
    {
        get { return _dcnf.Context.Mapping.GetTable(typeof(T)); }
    }

    private System.Data.Linq.Mapping.MetaType ClassMetadata
    {
        get { return _dcnf.Context.Mapping.GetMetaType(typeof(T)); }
    }
    #endregion
}
War es hilfreich?

Lösung

ich versucht sein würde vorschlagen, dass, ob Sie Betontypen verwenden oder nicht sollte keine Rolle spielen, als wenn Ihr mit Dependency Injection (Burg?) Die Repositorys erstellen (so können Sie sie mit verschiedenen Caches etc wickeln) dann Code-Basis wird so klug wie zuvor je nachdem, welche Art und Weise Sie es getan haben.

Dann fragen Sie einfach Ihre DI für ein Endlager. Z.B. für Burg:

public class Home {
  public static IRepository<T> For<T> {
    get {
      return Container.Resolve<IRepository<T>>();
    }
  }
}

Ich persönlich würde nicht Talsohle erreicht die Typen, bis Sie eine Notwendigkeit finden.

Ich denke, die andere Hälfte Ihrer Frage ist, ob Sie ganz einfach eine im Speicher Implementierung von IRepository zum Testen und Caching-Zwecke zur Verfügung stellen können. Dafür würde ich aufpassen, wie Linq-to-Objekte langsam sein kann und man könnte so etwas wie http: // www .codeplex.com / i4o nützlich.

Andere Tipps

Sie sollten nicht ein Repository für jede Tabelle erstellen.
Stattdessen sollten Sie ein Repository für alle ‚Entität root‘ (oder Aggregat root) erstellen, die in Ihrem Domain-Modell existiert. Sie können mehr über das Muster lernen und ein funktionierendes Beispiel siehe hier:

http://deviq.com/repository-pattern/

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top