Frage

Ich habe fast abgeschlossen durch mein Repository-Muster Implementierung eine IRepository<T> Schnittstelle, eine NewsRepository Klasse und eine News Einheit. Das Problem, das ich lief in versucht zu abstrahieren gemeinsamen Methoden zu einer Basis Repository-Klasse.

Ich kann nicht einen Weg zu abstrahieren der Get-Methode in den NewsRepository finden, da es einen bestimmten Linq Ausdruck enthält.

Meine Fragen sind: :

1) Wie kann ich abstrakt auf eine Basisklasse der public T Get(int id) Methode bitte? Die einzige Art, wie ich es getan haben, ist bei weitem anstelle eines int in Expression<Func<T,bool>> vorbei, aber dann, dass deosn't wirklich abstrahieren gemeinsames Verhalten als jede Unterklasse wird nach wie vor in einem Ausdruck übergeben müssen, die fast identisch ist in jedem Fall dh n => n.id == id.

2) Wie gehe ich in die Basisklasse auf der Update-Methode der Unterklasse GetViolations und Karten Methoden bitte? Ich stelle mir die Lösung ist möglicherweise von den Delegierten mit, aber ich konnte die Syntax zu kompilieren

nicht erhalten

Dies ist ein vereinfachte Satz der Codes -. In der Praxis Ich habe eine Save-Methode, die Update-tut und Insert und nicht nur die Aktualisierung hier gezeigt

public interface IRepository<T>
{
    T Get(int id);
    void Update(T item);
}

public class NewsRepository : IRepository<News>
{
    private Table<News> _newsTable;
    public NewsRepository(string connectionString)
    {
        _newsTable = new DataContext(connectionString).GetTable<News>();
    }

    public News Get(int id)
    {
        return _newsTable.SingleOrDefault(n => n.NewsId == id);
    }

    public void Update(News item)
    {
        var errors = item.GetRuleViolations();
        if (errors.Count > 0)
            throw new RuleException(errors);

        News dbNews = _newsTable.SingleOrDefault(n => n.NewsId == item.NewsId);
        map(dbNews, item);

        _newsTable.Context.SubmitChanges();
    }

    private void map(News dbNews, News news)
    {
        dbNews.Title = news.Title;
        dbNews.Article = news.Article;
    }
}

public class Repository<T> where T : class
{
    protected Table<T> _table;

    public Repository(Table<T> t)
    {
        _table = t;
    }

    //How do i do this??! - This doesn't compile due to T no having a NewsId
    public T Get(int id)
    {
    return _table.SingleOrDefault(n => n.NewsId == id);
    }

    //This seems to be a solution, but it's not really abstracting common behaviour as each
    //sub-class will still need to pass in the same linq expression...
    public T Get(Expression<Func<T,bool>> ex)
    {
        return _table.SingleOrDefault(ex);
    }

    public void Update(T item)
    {
        //How is it possible to pass in the GetRuleViolations and map functions to this method?
        var errors = item.GetRuleViolations();
        if (errors.Count > 0)
            throw new RuleException(errors);

        T dbNews = _table.SingleOrDefault(n => n.NewsId == item.NewsId);
        map(dbNews, item);

        _table.Context.SubmitChanges();
    }
}
War es hilfreich?

Lösung

  1. Es hilft wirklich, eine Layer Super für Entitäten . Sie werden eine Id-Eigenschaft teilen. Sie werden nicht mit einem Ausdruck zu tun haben, um die ID proeprty zu repräsentieren, werden Sie nur wissen, was es ist.

  2. Die Template-Methode Muster . In diesem Muster ist Ihre Basis-Update alle Arbeiten Hilfsmethoden, um fordern und Ihre abgeleiteten Klassen diese geschützten abstrakte Hilfsmethoden implementieren.

Andere Tipps

  1. L2S unterstützt weder Schicht übergeordnete Typen noch über Schnittstellenelemente in Abfragen, was ziemlich schwierig macht, wiederverwenden. Eine Möglichkeit ist, um dynamisch einen Ausdruck Baum zu bauen. Es ist ein bisschen chaotisch, aber wenn Sie es zu Ihrem Basisklasse Repository isolieren ist es nicht so schlimm.

Hier ist ein Beispiel:

public interface IEntity
{
    int Id { get; }
}

public partial class News : IEntity
{
}

public class Repository<T> where T : class, IEntity
{

    private readonly DataContext _db;

    public Repository(DataContext db)
    {
        _db = db;
    }

    public T Get(int id)
    {
        Expression<Func<T, bool>> hasId = HasId(id);
        return _db.GetTable<T>().Single(hasId);
    }

    // entity => entity.Id == id;   
    private Expression<Func<T, bool>> HasId(int id)
    {
        ParameterExpression entityParameter = Expression.Parameter(typeof (T), "entity");
        return Expression.Lambda<Func<T, bool>>(
            Expression.Equal(
                Expression.Property(entityParameter, "Id"),
                Expression.Constant(id)
                ),
            new[] {entityParameter}
            );
    }
}

Siehe auch http://msdn.microsoft.com/en-us /library/bb397951.aspx

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