سؤال

لدي طريقة تحديد طبقة البيانات التي تُرجع جدول بيانات.يتم استدعاؤه من أسلوب طبقة الأعمال والذي يجب أن يُرجع بعد ذلك قائمة عامة مكتوبة بقوة.

ما أريد القيام به يشبه إلى حد كبير (ولكن ليس نفس) هذا السؤال:
كيف يمكنك تحويل DataTable إلى قائمة عامة؟

الأمر المختلف هو أنني أريد أن تحتوي القائمة على كائنات مكتوبة بقوة بدلاً من صفوف البيانات (أيضًا، ليس لدي linq متاح هنا حتى الآن).

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

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

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

المحلول

هل تعرف هيكل DataTable والكائن كتبته في وقت مبكر؟ هل يمكن استخدام مندوب للقيام التعيين. إذا كنت لا (أي كل ما تعرفه هو Type وخصائص) هناك طرق لتسريع الوصول عضوا الحيوي (مثل HyperDescriptor).

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

هل لك أن توضح أي من هذه النقاط؟ ويمكنني أن أضيف الكثير من التفاصيل ...

وفي أبسط، ما هو الخطأ في:

DataTable table = new DataTable {
    Columns = {
        {"Foo", typeof(int)},
        {"Bar", typeof(string)}
     }
};
for (int i = 0; i < 5000; i++) {
    table.Rows.Add(i, "Row " + i);
}

List<MyType> data = new List<MyType>(table.Rows.Count);
foreach (DataRow row in table.Rows) {
    data.Add(new MyType((int)row[0], (string)row[1]));
}

و(المشاكل في أعلاه قد توجيه النهج الصحيح ...)

نصائح أخرى

مشكلة العينة أعلاه هي أنها بطيئة للغاية.لدي DataTable يحتوي على حوالي 400 صف ويستغرق هذا التحويل 5 أو 6 ثوانٍ!

يبدو أنها مهمة شائعة جدًا، لذلك أنا مندهش لعدم رؤية شخص هنا لديه حل أكثر أداءً.

* تحديث!!*فقط للركلات، اعتقدت أنني سأحاول التحويل باستخدام LINQ بدلاً من التكرار عبر DataTable والإضافة إلى قائمتي.وفيما يلي ما فعلته:

   List<MyObject> returnList = new List<MyObject>();

   MyDataTable dtMyData = new MyTableAdapter().GetMyData();

   returnLists = (from l in dtMyData
                 select new MyObject
                 {
                    Active = l.IsActive,
                    Email = l.Email,
                    //...
                    //About 40 more properties
                    //...
                    ZipCode = l.Zipcode
                  }).ToList();

استغرقت الطريقة الأولى (التكرار خلال كل صف) 5.3 ثانية واستغرقت الطريقة التي تستخدم LINQ 1.8 ثانية!

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

ويقول لتحديد مجموعة مخصصة الخاص التي تطبق IList<T>. ثم يمكن أن يكون حقلين الداخلية - في إشارة إلى جمع datarows وList<T>. سيتم تهيئة List<T> لطول جمع datarows ولكن مع القيم الخالية.

والآن في مفهرس هل يمكن معرفة ما اذا كان List<T> يحتوي على القيمة في هذا المؤشر، وإذا لم يمكنك إنشاء الكائن باستخدام بأي وسيلة كانت ستكون مفيدة وتخزينها هناك قبل إعادته.

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

وربما تحتاج الكائنات الخاصة بك منشئ أخذ DataRow أو كنت في حاجة إلى نوع من مصنع لخلق لهم، ولكن هذا موضوع آخر.

وفقط لإعطاء بعض أكثر سهولة - الود للإجابة مارك في التطبيق وحدة تحكم بسيطة:

class Program
{
    static void Main(string[] args)
    {
        //define a DataTable obj
        DataTable table = new DataTable
        {
            Columns = {
            {"Foo", typeof(int)},
            {"Bar", typeof(string)}
         }
        };
        //populate it the DataTable 
        for (int i = 0; i < 3; i++)
        {
            table.Rows.Add(i, "Row " + i);
        }

        List<MyType> listWithTypedObjects= new List<MyType>(table.Rows.Count);
        foreach (DataRow row in table.Rows)
        {
            listWithTypedObjects.Add(new MyType((int)row[0], (string)row[1]));
        }

        Console.WriteLine(" PRINTING THE POPULATED LIST ");
        foreach (MyType objMyType in listWithTypedObjects)
        {
            Console.Write(" I have object of the type " + objMyType.ToString() + " => " );
            Console.Write(" with Prop1OfTypeInt " + objMyType.Prop1OfTypeInt.ToString() + " , ");
            Console.WriteLine(" with Prop1OfTypeInt " + objMyType.Prop2OfTypeString.ToString() + "  "); 
        }

        Console.WriteLine(" \n \n \n HIT A KEY TO EXIT THE PROGRAM ");
        Console.ReadKey();
    }
}

class MyType {

    public int Prop1OfTypeInt { get; set; }
    public string Prop2OfTypeString { get; set; } 

    /// <summary>
    /// Note the order of the passed parameters is important !!!
    /// </summary>
    public MyType( int prop1OfTypeInt , string prop2OfTypeString)
    {
        this.Prop1OfTypeInt = prop1OfTypeInt;
        this.Prop2OfTypeString = prop2OfTypeString; 

    }
}
public partial class issuereceive_manageroffice_bal
{
    public int issue_id{get;set;}
    public string process{get;set;}
    public DateTime issue_date{get;set;}
    public TimeSpan issue_time{get;set;}
    public string eg_no{get;set;}
    public string lotno{get;set;}
    public string clarity{get;set;}
    public string sieves{get;set;}
    public string shape{get;set;}
    public double issue_carat{get;set;}
    public int issue_pieces{get;set;}
    public int receive_pieces{get;set;}
    public double receive_carat{get;set;}
    public int kp_pieces{get;set;}
    public decimal kp_carat{get;set;}
    public double loss{get;set;}
    public string issue_manager{get;set;}
    public string issue_by{get;set;}
    public string receive_by{get;set;}
    public int status{get;set;}
    public DateTime receive_date{get;set;}
    public string receive_time{get;set;}
    public int factory_id{get;set;}

}


List<issuereceive_manageroffice_bal> issue_receive_list = new List<issuereceive_manageroffice_bal>();
issue_receive_list =
      (from DataRow dr in DataTable.Rows
      select new issuereceive_manageroffice_bal()
           {
               issue_id = 0,
               issue_time = TimeSpan.Parse("0"),
               receive_time = null,
               shape = null,
               process = dr["process"].ToString(),
               issue_date = Convert.ToDateTime(dr["issue_date"]),
               eg_no = dr["eg_no"].ToString(),
               lotno = dr["lotno"].ToString(),
               clarity = dr["clarity"].ToString(),
               sieves = dr["sieves"].ToString(),
               issue_carat = dr["issue_carat"].ToString() != "" ? double.Parse(dr["issue_carat"].ToString()) : 0,
               issue_pieces = dr["issue_pieces"].ToString() != "" ? int.Parse(dr["issue_pieces"].ToString()) : 0,
               receive_carat = dr["receive_carat"].ToString() != "" ? double.Parse(dr["receive_carat"].ToString()) : 0,
               kp_pieces = dr["kp_pieces"].ToString() != "" ? int.Parse(dr["kp_pieces"].ToString()) : 0,
               kp_carat = dr["kp_carat"].ToString() != "" ? decimal.Parse(dr["kp_carat"].ToString()) : 0,
               loss = dr["loss"].ToString() != "" ? double.Parse(dr["loss"].ToString()) : 0,
               issue_manager = dr["lotno"].ToString(),
               issue_by = dr["issue_by"].ToString(),
               receive_by = dr["receive_by"].ToString(),
               status = dr["status"].ToString() != "" ? int.Parse(dr["status"].ToString()) : 0,
               receive_date = Convert.ToDateTime(dr["receive_date"]),
               factory_id = dr["factory_id"].ToString() != "" ? int.Parse(dr["factory_id"].ToString()) : 0,

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