سؤال

كيف يمكنني تعيين كائن DataReader في كائن فئة باستخدام Generics؟

على سبيل المثال، أحتاج إلى القيام بما يلي:

public class Mapper<T>
    {
        public static List<T> MapObject(IDataReader dr)
        {
            List<T> objects = new List<T>();

            while (dr.Read())
            {
                //Mapping goes here...
            }

            return objects;
        }
    }

في وقت لاحق أحتاج إلى استدعاء هذه الطريقة الفئة مثل ما يلي:

IDataReder dataReader = DBUtil.Fetchdata("SELECT * FROM Book");

List<Book> bookList = Mapper<Book>.MapObject(dataReder);

foreach (Book b in bookList)
{
     Console.WriteLine(b.ID + ", " + b.BookName);
}

لاحظ أنه، يجب أن تكون الطبقة المخططات قادرة على خريطة كائن أي نوع يمثله T.

هل كانت مفيدة؟

المحلول

أنا أستعمل valueinjecter. لهذا

أنا أفعل مثل هذا:

 while (dr.Read())
  {
      var o = new User();
      o.InjectFrom<DataReaderInjection>(dr);
      yield return o;
  }

ستحتاج إلى هذه القيمة لهذا العمل:

public class DataReaderInjection : KnownSourceValueInjection<IDataReader>
    {
        protected override void Inject(IDataReader source, object target, PropertyDescriptorCollection targetProps)
        {
            for (var i = 0; i < source.FieldCount; i++)
            {
                var activeTarget = targetProps.GetByName(source.GetName(i), true);
                if (activeTarget == null) continue;

                var value = source.GetValue(i);
                if (value == DBNull.Value) continue;

                activeTarget.SetValue(target, value);
            }
        }
    }

نصائح أخرى

حسنا، لا أعرف ما إذا كان يناسب هنا، ولكن يمكنك استخدام الكلمة الأساسية العائد

public static IEnumerable<T> MapObject(IDataReader dr, Func<IDataReader, T> convertFunction)
        {
            while (dr.Read())
            {
                yield return convertFunction(dr);
            }
        }

يمكنك استخدام فئة LateBinder هذه كتبت: http://codecube.net/2008/12/new-latebinder/.

كتبت وظيفة أخرى باستخدام: http://codecube.net/2008/12/using-the-latebinder/

سيكون من الصعب للغاية القيام بذلك لسبب أنك تحاول في الأساس تعيين اثنين من المجهولين معا. في كائنه العام، النوع غير معروف، وفي dataReader الخاص بك الجدول غير معروف.

إذن ما أقترحه هو إنشاء سمة نوع من الأعمدة لإرفاق خصائص كيانك. ثم ننظر من خلال سمات هذه الخصائص وحاول البحث عن البيانات من تلك السمات في DataReader.

ستكون المشكلة الأكبر الخاصة بك، ما يحدث إذا لم يتم العثور على أحد الخصائص في القارئ، أو العكس بالعكس، لم يتم العثور على أحد الأعمدة الموجودة في القارئ في الكيان.

حظا سعيدا، ولكن إذا كنت ترغب في القيام بشيء من هذا القبيل، فمن المحتمل أنك تريد الفم أو على الأقل نوعا من تطبيق السجل النشط.

أسهل طريقة يمكنني أن أفكر في دفأة ستكون لتزويد Func<T,T> مندوب لتحويل كل عمود وبناء كتابك.

بدلا من ذلك، إذا اتبعت بعض الاتفاقيات، فيمكنك التعامل مع هذا عبر الانعكاس. على سبيل المثال، إذا تم تعيين كل عمود إلى خاصية في الكائن الناتج باستخدام نفس الاسم، وأنت مقيد ر في MAPPER الخاص بك لتوفير رايات قابلة للإصابة، يمكنك استخدام التفكير لتعيين قيمة كل خاصية إلى القيمة في العمود المقابل وبعد

لا أعتقد أنك ستتمكن من التعرف على تحديد العلاقة بين الحقول في شكل ما. إلقاء نظرة على هذه المقالة وإيلاء اهتمام خاص لكيفية تحديد التعيين، فقد يعمل من أجلك.

http://www.c-sharpcorner.com/uploadfile/rmcochran/alegant_dal0521212006130957pm/elegant_dal.aspx.

ماذا عن متابعة

abstract class DataMapper
{
    abstract public object Map(IDataReader);
}

class BookMapper : DataMapper
{
   override public object Map(IDataReader reader)
   {
       ///some mapping stuff
       return book;
   }
}

public class Mapper<T>
{
    public static List<T> MapObject(IDataReader dr)
    {
        List<T> objects = new List<T>();
        DataMapper myMapper = getMapperFor(T);
        while (dr.Read())
        {
            objects.Add((T)myMapper(dr));
        }

        return objects;
    }

    private DataMapper getMapperFor(T myType)
    {
       //switch case or if or whatever
       ...
       if(T is Book) return bookMapper;

    }
}

لا أعرف ما إذا كان صحيحا صحيحا، لكنني آمل أن تحصل على الفكرة.

ماذا عن استخدام بطلاقة ado.net. ?

القي نظرة على http://caprisoft.codeplex.com.

أود أن أوصي بأن تستخدم Automapper. لهذا.

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