سؤال

أنا أستعد لبدء مشروع ويب asp.net جديد، وسأقوم بالانتقال إلى LINQ-to-SQL.لقد قمت بالقليل من العمل للحصول على إعداد طبقة البيانات الخاصة بي باستخدام بعض المعلومات التي وجدتها مايك هادلو يستخدم واجهة وأدوية عامة لإنشاء مستودع لكل جدول في قاعدة البيانات.اعتقدت أن هذا كان نهجا مثيرا للاهتمام في البداية.ومع ذلك، أعتقد الآن أنه قد يكون من المنطقي إنشاء فئة مستودع أساسية والوراثة منها لإنشاء فئة TableNameRepository للجداول التي أحتاج إلى الوصول إليها.

ما هو النهج الذي سيسمح لي بإضافة وظائف محددة إلى الجدول بطريقة نظيفة وقابلة للاختبار؟هنا هو تنفيذ المستودع الخاص بي كمرجع.

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

المحلول

سأميل إلى اقتراح أنه لا يهم ما إذا كنت تستخدم أنواعًا محددة أم لا، كما لو كنت تستخدم حقن التبعية (القلعة؟) لإنشاء المستودعات (حتى تتمكن من تغليفها بذاكرة تخزين مؤقت مختلفة وما إلى ذلك) فإن قاعدة التعليمات البرمجية الخاصة بك ستكون لا شيء أكثر حكمة مهما كانت الطريقة التي قمت بها.

ثم فقط اطلب من شركة DI الخاصة بك الحصول على مستودع.على سبيل المثالللقلعة:

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

أنا شخصياً لن أقوم بتحديد الأنواع حتى تجد الحاجة إليها.

أعتقد أن النصف الآخر من سؤالك هو ما إذا كان يمكنك بسهولة توفير تطبيق IRepository في الذاكرة لأغراض الاختبار والتخزين المؤقت.لهذا يجب أن أحذر من أن الارتباط بالكائنات يمكن أن يكون بطيئًا وقد تجد شيئًا من هذا القبيل http://www.codeplex.com/i4o مفيد.

نصائح أخرى

لا ينبغي عليك إنشاء مستودع لكل جدول.
بدلاً من ذلك، يجب عليك إنشاء مستودع لكل "جذر كيان" (أو جذر مجمع) موجود في نموذج المجال الخاص بك.يمكنك معرفة المزيد حول النمط ورؤية مثال عملي هنا:

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

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