سؤال

لقد أكملت تقريبا تنفيذ نمط مستودعي من خلال وجود IRepository<T> واجهة، أ. NewsRepository الطبقة و News شخصية. كانت المشكلة التي هربت فيها تحاول تجريد الأساليب المشتركة لفئة مستودع قاعدة.

لم أستطع إيجاد طريقة لتجريد طريقة الحصول على NewsRepository كما أنه يحتوي على تعبير LinQ معين.

أسئلتي:

1) كيف يمكنني التخلص من فئة قاعدة public T Get(int id) طريقة من فضلك؟ الطريقة الوحيدة التي قمت بها حتى الآن عن طريق المرور Expression<Func<T,bool>> بدلا من int، ولكن بعد ذلك أن Deos غير مجردة سلوك مشترك حقا لأن كل فئة فرعية ستظل بحاجة إلى تمرير تعبيرا متطابقا تقريبا في كل حالة أي n => n.id == id.

2) كيف يمكنني المرور في الفئة الأساسية في طريقة التحديث طريقة GetViolations الفئة الفرعية وأساليب الخريطة من فضلك؟ أتصور الحل ربما باستخدام المندوبين، لكنني لم أستطع الحصول على بناء الجملة لتجميع

هذه مجموعة مبسطة من التعليمات البرمجية - في الممارسة العملية، لدي طريقة حفظ تقوم بتحديث وإدخال التحديث بدلا من مجرد التحديث الذي يظهر هنا.

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();
    }
}
هل كانت مفيدة؟

المحلول

  1. انها حقا يساعد على الحصول على طبقة Supertype للكيانات. وبعد سيقومون بممتلكات معرف. لن تضطر إلى التعامل مع تعبير لتمثيل ProPerty الهوية، ستعرف فقط ما هو عليه.

  2. ال نموذج طريقة القالب. وبعد في هذا النمط، يقوم التحديث القاعدي بتحديثك جميع أساليب المساعد في العمل بالترتيب، وتنفذ فئاتك المشتقة من أساليب المساعد المحمية المحمية.

نصائح أخرى

  1. لا يدعم L2S LITEER SuperTypes ولا تستخدم أعضاء الواجهة في استفسارات، مما يجعل إعادة استخدامها صعبة للغاية. خيار واحد هو بناء شجرة تعبير ديناميكيا. إنه فوضوي بعض الشيء، ولكن إذا عزلته لمستودع الطبقة الأساسية، فليس هذا سيئا.

هنا مثال:

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}
            );
    }
}

أنظر أيضا http://msdn.microsoft.com/en-us/library/bb397951.aspx.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top