سؤال

لدي علاقة Master Detail بين فصلين. سوف تحتوي الفئة الرئيسية على قائمة بالعديد من التفاصيل. حاليا كنت أستخدم

public class Master: cloneable<T>
{
     //other properties here...
    private List<detailClass> details
    public List<detailClass> Details
    {
        get { return details; }
    }
}

داخل الفصل الرئيسي. أثناء حفظ هذه الفئة ، أحتاج إلى استخدام DataTable لقائمة التفاصيل قبل نقلها إلى SP. (نظرًا لأننا نستخدم معاملات قيمة الجدول في SQL2008). سبب استخدام TVP ، هو أن 1 Master يمكن أن يحتوي على ما يصل إلى 10K تفاصيل ، و TVP هو وسيلة فعالة للغاية لإلقاء كل هذه المعلومات في DB بسرعة كبيرة.

QS: عندما أقوم بتحويل القائمة إلى DataTable لإدخال DB ، هناك استخدام مزدوج للذاكرة لنفس البيانات. هل هناك طريقة أفضل لتوفير التفاصيل في الماجستير ، بخلاف استخدام DataTable مباشرة؟

QS: كان الخيار التالي هو محاولة استخدام تفاصيل القائمة ، والقيام DataTable.ImporTrow (صف). لكنني لا أعرف ، كيف يمكنني إضافة بيانات إلى صف ، دون تحديد أي أعمدة. أنا أيضًا لا أعرف كيف يمكن لأي كائن خارجي أن يتمكن من الحصول على حقول التفاصيل الفردية في مثل هذه القائمة.


التالية إجابة كاسبيرون لقد استخدمت IEnumerable<SqldataRecord> الطريقة وتمكنت من إدراج البيانات عن طريق الدفق وبدون الاضطرار إلى إنشاء بيانات إضافية في الذاكرة. لكي أكون مفيدًا لأي شخص آخر يبحث عن حل مماثل ، أقوم بنشر الكود أدناه.

public class DetailCollection: List<Detail>, IEnumerable<SqlDataRecord>
{
    IEnumerator<SqlDataRecord> IEnumerable<SqlDataRecord>.GetEnumerator()
    {
        // mapping the properties of the Detail object to the 
        // user defined table type in sql
        SqlMetaData[] metaDataArray = new SqlMetaData[4];

        //-1 indicates varchar(max) sql data type
        metaDataArray[0] = new SqlMetaData("Col1", SqlDbType.VarChar, -1); 
        metaDataArray[1] = new SqlMetaData("Col2", SqlDbType.TinyInt);
        metaDataArray[2] = new SqlMetaData("Col3", SqlDbType.VarChar,100);
        metaDataArray[3] = new SqlMetaData("Col4", SqlDbType.Int);

        SqlDataRecord sdr = new SqlDataRecord(metaDataArray);


        foreach (Detail detailRecord in this)
        {
                    sdr.SetValue(0, detailRecord.Property1);
                    sdr.SetValue(1, Convert.ToByte(detailRecord.Property2));
                    sdr.SetValue(2, detailRecord.Property3);
                    sdr.SetValue(3, detailRecord.Property4);
                    yield return sdr;
        }
    }
}
هل كانت مفيدة؟

المحلول

يمكنك دفق النتائج إلى أ معلمة ذات قيمة الجدول باستخدام واحدة من طريقتين:

  • IEnumerable<SqlDataRecord> - يمكنك استخدام yield return في IEnumerable<SqlDataRecord> التنفيذ (أو LINQ ، وهو أسهل) لإنشاء حل دفق.
  • DbDataReader التنفيذ - يمكنك إنشاء تنفيذ سيأخذ إشارة إلى قائمتك وتوفير التحولات المناسبة حيث يتم تعداد القارئ من خلال.

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

لمزيد من المعلومات ، راجع قسم MSDN بعنوان "المعلمات ذات قيمة الجدول في SQL Server 2008"، على وجه التحديد ،" تكوين مثال SQLParameter "و" صفوف البث مع DataReader ".

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