الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

مشكله فى ال ()ToDataTable فى LINQ

بدأه عمرو الصعيدي في 2 أبريل 2010 · 11 رد · 1,068 مشاهدة · في Microsoft Visual C#.NET
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

واجهتنى مشكله عند استخدام الداله ()ToDataTable فى ملئ ال DataSet عن طريق ال LINQ

حيث أن كود الداله

  public static DataTable ToDataTable<T>(this IEnumerable<T> varlist)
        {
            DataTable dtReturn = new DataTable();

            // column names 
            PropertyInfo[] oProps = null;

            if (varlist == null) return dtReturn;

            foreach (T rec in varlist)
            {
                // Use reflection to get property names, to create table, Only first time, others will follow 
                if (oProps == null)
                {
                    oProps = ((Type)rec.GetType()).GetProperties();
                    foreach (PropertyInfo pi in oProps)
                    {
                        Type colType = pi.PropertyType;

                        if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>)))
                        {
                            colType = colType.GetGenericArguments()[0];
                        }

                        dtReturn.Columns.Add(new DataColumn(pi.Name, colType));
                    }
                }

                DataRow dr = dtReturn.NewRow();

                foreach (PropertyInfo pi in oProps)
                {
                    dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue
                    (rec, null);
                }

                dtReturn.Rows.Add(dr);
            }
            return dtReturn;
        }

فعند استخدامها فى جلب البيانات فى ال DataSet عن طريق الكود الأتى مثلا

DataSet DS = new DataSet();

         var query = from c in EntryDetails
                        where c.EntryID == 10
                        select c;

            DS.Tables.Add(query.ToDataTable());

يظهر خطأ فى ال Debugging كما فى الصوره

post-207223-12701935184031_thumb.jpg

تم تعديل هذه المشاركة بواسطة amr.alsaidy في 2 أبريل 2010 في 10:32

 وممّا زادنـــي شرفــاً وتيهــاً   **  وكدت بأخمصي أطأ الثريّا

دخولي تحت قولك يا عبادي  **   وأن صيّرت أحمد لي نبيّـاً

#2

جرب تصدير ناتج الاستعلام إلى List(T) باستخدام ال ToList Extension Method قبل التحويل.

تم تعديل هذه المشاركة بواسطة IslamDotNet في 2 أبريل 2010 في 14:09

#3

جزاك الله خيرا أخى

جربت التصدير الى ToList()

عن طريق الكود

DataSet DS = new DataSet();

         var query = from c in EntryDetails
                        where c.EntryID == 10
                        select c;
            query.ToList()
            DS.Tables.Add(query.ToDataTable());

ولكن لم يجدى الامر

استخدمت داله اخرى ()ToADOTable الموجوده فى هذه الصفحه واتبعت الخطوات فيها جيدا

http://weblogs.asp.net/stevesloka/archive/2008/01/28/linq-to-datatable.aspx

وكودها هو

public static DataTable ToADOTable<T>(this IEnumerable<T> varlist, CreateRowDelegate<T> fn)
        {

            DataTable dtReturn = new DataTable();

            // column names

            PropertyInfo[] oProps = null;

            // Could add a check to verify that there is an element 0

            foreach (T rec in varlist)
            {

                // Use reflection to get property names, to create table, Only first time, others will follow

                if (oProps == null)
                {

                    oProps = ((Type)rec.GetType()).GetProperties();

                    foreach (PropertyInfo pi in oProps)
                    {

                        Type colType = pi.PropertyType; if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>)))
                        {

                            colType = colType.GetGenericArguments()[0];

                        }

                        dtReturn.Columns.Add(new DataColumn(pi.Name, colType));

                    }

                }

                DataRow dr = dtReturn.NewRow(); foreach (PropertyInfo pi in oProps)
                {

                    dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue(rec, null);

                }

                dtReturn.Rows.Add(dr);

            }

            return (dtReturn);

        }

        public delegate object[] CreateRowDelegate<T>(T t);

ولكن ظهر نفس الخطأ

فهل يعرف أحد سبب الخطأ ؟

 وممّا زادنـــي شرفــاً وتيهــاً   **  وكدت بأخمصي أطأ الثريّا

دخولي تحت قولك يا عبادي  **   وأن صيّرت أحمد لي نبيّـاً

#4

الأرجح أن المشكلة في ال Enumerator نفسه , ضع لنا ال StackTrace أو أرفع مشروع صغير لتوضيح المشكلة بالضبط.

#5

ال stackTrace

"   at System.Data.SqlClient.SqlBuffer.get_Int32()\r\n   at System.Data.SqlClient.SqlDataReader.GetInt32(Int32 i)\r\n   at Read_EntryDetailsTbl(ObjectMaterializer`1 )\r\n   at System.Data.Linq.SqlClient.ObjectReaderCompiler.ObjectReader`2.MoveNext()\r\n   at BONIAN.AIS.ConvertDataTable.ToADOTable[T](IEnumerable`1 varlist, CreateRowDelegate`1 fn) in C:\\BONIAN.AIS\\BONIAN.AIS\\ConvertDataTable.cs:line 31\r\n   at BONIAN.AIS.InvoiceCss.ShowEntries(DataGridView DT, String Sqlstr, DateTimePicker Dtp) in C:\\BONIAN.AIS\\BONIAN.AIS\\InvoiceCss.cs:line 244\r\n   at BONIAN.AIS.VouJournal.ShowLast() in C:\\BONIAN.AIS\\BONIAN.AIS\\VouJournal.cs:line 67\r\n   at BONIAN.AIS.VouJournal.Entries_Load(Object sender, EventArgs e) in C:\\BONIAN.AIS\\BONIAN.AIS\\VouJournal.cs:line 104\r\n   at System.Windows.Forms.Form.OnLoad(EventArgs e)\r\n   at System.Windows.Forms.Form.OnCreateControl()\r\n   at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)\r\n   at System.Windows.Forms.Control.CreateControl()\r\n   at System.Windows.Forms.Control.WmShowWindow(Message& m)\r\n   at System.Windows.Forms.Control.WndProc(Message& m)\r\n   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)\r\n   at System.Windows.Forms.ContainerControl.WndProc(Message& m)\r\n   at System.Windows.Forms.Form.WmShowWindow(Message& m)\r\n   at System.Windows.Forms.Form.WndProc(Message& m)\r\n   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)\r\n   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)\r\n   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)\r\n   at System.Windows.Forms.SafeNativeMethods.ShowWindow(HandleRef hWnd, Int32 nCmdShow)\r\n   at System.Windows.Forms.Control.SetVisibleCore(Boolean value)\r\n   at System.Windows.Forms.Form.SetVisibleCore(Boolean value)\r\n   at System.Windows.Forms.Form.Show(IWin32Window owner)\r\n   at BONIAN.AIS.MainForm.journalEntryToolStripMenuItem_Click(Object sender, EventArgs e) in C:\\BONIAN.AIS\\BONIAN.AIS\\MainForm.cs:line 33\r\n   at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)\r\n   at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)\r\n   at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)\r\n   at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)\r\n   at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)\r\n   at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)\r\n   at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)\r\n   at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)\r\n   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)\r\n   at System.Windows.Forms.Control.WndProc(Message& m)\r\n   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)\r\n   at System.Windows.Forms.ToolStrip.WndProc(Message& m)\r\n   at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)\r\n   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)\r\n   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)\r\n   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)\r\n   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)\r\n   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)\r\n   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)\r\n   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)\r\n   at System.Windows.Forms.Application.Run(Form mainForm)\r\n   at BONIAN.AIS.Program.Main() in C:\\BONIAN.AIS\\BONIAN.AIS\\Program.cs:line 18\r\n   at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)\r\n   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)\r\n   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()\r\n   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)\r\n   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)\r\n   at System.Threading.ThreadHelper.ThreadStart()"

 وممّا زادنـــي شرفــاً وتيهــاً   **  وكدت بأخمصي أطأ الثريّا

دخولي تحت قولك يا عبادي  **   وأن صيّرت أحمد لي نبيّـاً

#6

أنا بالعادة لا أستخدم سي شارب

ولكن ملاحظة إن كنت أعمل على البيزيك

لماذا لا تعتمد على الاستدلال المحلي على النوع ألغي T من هذا السطر ودع المترجم يحدد النوع تلقائيا

foreach (T rec in varlist)

تم تعديل هذه المشاركة بواسطة محمد سامر أبو سلو في 5 أبريل 2010 في 12:31

عن عائشة رضي الله عنها أن النبي صلى الله عليه وسلم قال: إن الله يحب إذا عمل أحدكم عملا أن يتقنه

نعيب زماننا والعيب فينا ... وما لزماننا عيب سوانا

ونهجو ذا الزمان بغير ذنب ... ولو نطق الزمان لنا هجانا

محمد سامر أبو سلو

#7

لن يفيد الاستدلال المحلي على النوع هنا,(باستخدام var Keyword ) حتى إذا قمت بذلك فالمترجم سيستدل على أن كل عنصر داخل ال Sequence هو من النوع T يعني لم يتغير شيئ.

الاستدلال المحلي على النوع مفيد فقط وقت الترجمة وليس وقت التشغيل في سي شارب . ومشكلة صاحب الموضوع تحدث وقت التشغيل.

بالنسبة للمشكلة أعتقد أنه يجب باستخدام ال Cast Extension Method

DS.Tables.Add(query.Cast<EntityDetail>().ToDataTable());

تم تعديل هذه المشاركة بواسطة IslamDotNet في 5 أبريل 2010 في 22:20

#8

أخى الحمد لله توصلت لحل المشكله

وهى أننى كنت معرف فئه للجدول يدويا بالشكل التالى

        [Table(Name = "dbo.EntryDetails")]
        public class EntryDetail
        {
            [Column(IsPrimaryKey = true)]
            public DateTime EntryDate;
            [Column(IsPrimaryKey = true)]
            public int EntryID;
            [Column]
            public int AmountDr;
            [Column]
            public int AmountCr;
            [Column]
            public string AccName;
            [Column]
            public int AccID;
        }

ولكنى جربت الفئه التى ينشئها ال DataContext فى ال design

[Table(Name = "dbo.EntryDetails")]
        public class EntryDetail
        {
            private System.DateTime _EntryDate;

            private int _EntryID;

            private System.Nullable<decimal> _AmountDr;

            private System.Nullable<decimal> _AmountCr;

            private string _AccName;

            private int _AccID;

            public EntryDetail()
            {
            }

            [Column(Storage = "_EntryDate", DbType = "DateTime NOT NULL")]
            public System.DateTime EntryDate
            {
                get
                {
                    return this._EntryDate;
                }
                set
                {
                    if ((this._EntryDate != value))
                    {
                        this._EntryDate = value;
                    }
                }
            }

            [Column(Storage = "_EntryID", DbType = "Int NOT NULL")]
            public int EntryID
            {
                get
                {
                    return this._EntryID;
                }
                set
                {
                    if ((this._EntryID != value))
                    {
                        this._EntryID = value;
                    }
                }
            }

            [Column(Storage = "_AmountDr", DbType = "Money")]
            public System.Nullable<decimal> AmountDr
            {
                get
                {
                    return this._AmountDr;
                }
                set
                {
                    if ((this._AmountDr != value))
                    {
                        this._AmountDr = value;
                    }
                }
            }

            [Column(Storage = "_AmountCr", DbType = "Money")]
            public System.Nullable<decimal> AmountCr
            {
                get
                {
                    return this._AmountCr;
                }
                set
                {
                    if ((this._AmountCr != value))
                    {
                        this._AmountCr = value;
                    }
                }
            }

            [Column(Storage = "_AccName", DbType = "VarChar(100) NOT NULL", CanBeNull = false)]
            public string AccName
            {
                get
                {
                    return this._AccName;
                }
                set
                {
                    if ((this._AccName != value))
                    {
                        this._AccName = value;
                    }
                }
            }

            [Column(Storage = "_AccID", DbType = "Int NOT NULL")]
            public int AccID
            {
                get
                {
                    return this._AccID;
                }
                set
                {
                    if ((this._AccID != value))
                    {
                        this._AccID = value;
                    }
                }
            }

        }

ولكنى لا أعرف ما الخطأ فى الكود اليدوى

 وممّا زادنـــي شرفــاً وتيهــاً   **  وكدت بأخمصي أطأ الثريّا

دخولي تحت قولك يا عبادي  **   وأن صيّرت أحمد لي نبيّـاً

#9

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

, لكن أتساءل هل حصلت على نتائج عندما قمت بتنفيذ الاستعلام من قاعدة البيانات باستخدام فئتك السابقة ؟؟

تم تعديل هذه المشاركة بواسطة IslamDotNet في 5 أبريل 2010 في 22:30

#10

نعم الكود الثانى اشتغل معى تمام

هل تستطيع التعديل على الكود الأول

 وممّا زادنـــي شرفــاً وتيهــاً   **  وكدت بأخمصي أطأ الثريّا

دخولي تحت قولك يا عبادي  **   وأن صيّرت أحمد لي نبيّـاً

#11

إذا أردت التعديل على فئتك عليك أن تعرفها تماماً كما قام بتعريفها ال Code Generator حتى تضمن أن الكود سيعمل بشكل سليم .

تم تعديل هذه المشاركة بواسطة IslamDotNet في 5 أبريل 2010 في 22:53

#12

السلام عليكم

واجهتني نفس المشكلة، وبالبحث وجدت الدالة التالية:

CopyToDataTable

والتي يمكن استخدامها بعد استيراد Imports System.Data.DataTableExtensions

مواضيع مشابهة