سؤال

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

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

المحلول

لا يحتوي LINQ to SQL حقًا على قصة من المستوى n التي رأيتها، نظرًا لأن الكائنات التي تنشئها يتم إنشاؤها في الفصل مع بقية العناصر، فليس لديك حقًا تجميع يمكنك الرجوع إليه بشكل جيد من خلاله شيء مثل خدمات الويب وما إلى ذلك.

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

هذا إذا كنت أفهم ما تحاول الوصول إليه :\

لقد طرحت نفس السؤال على ScottGu على مدونته عندما بدأت النظر إليه لأول مرة - لكنني لم أر سيناريو أو تطبيقًا واحدًا في البرية يستخدم LINQ إلى SQL بهذه الطريقة.تعد مواقع الويب مثل Rob Connery's Storefront أقرب إلى الموفر.

نصائح أخرى

حسنًا، روكفورد لوتكا من المحزن أن LINQ to SQL هي تقنية رائعة لجلب البيانات من قاعدة البيانات.ويقترح أنه بعد ذلك يجب أن يتم ربطهم "للوصول إلى كائنات المجال" (ويعرف أيضًا باسم.كائنات CSLA).

على محمل الجد، كان LINQ to SQL يدعم بنية n-tier DataContext.Update طريقة.

قد ترغب في النظر في ADO .Net Entity Framework كبديل لـ LINQ إلى SQL، على الرغم من أنه يدعم LINQ أيضًا.أعتقد أن LINQ to SQL مصمم ليكون خفيف الوزن وبسيطًا إلى حد ما، في حين أن Entity Framework أكثر ثقلًا وربما أكثر ملاءمة لتطبيقات المؤسسات الكبيرة.

حسنًا، سأقدم لنفسي حلًا واحدًا ممكنًا.

لم تكن الإدخالات/التحديثات مشكلة على الإطلاق؛يمكنك تغليف منطق الأعمال بطريقة حفظ/تحديث؛على سبيل المثال

public class EmployeesDAL
{
    ...
    SaveEmployee(Employee employee)
    {
        //data formatting
        employee.FirstName = employee.FirstName.Trim();
        employee.LastName = employee.LastName.Trim();

        //business rules
        if(employee.FirstName.Length > 0 && employee.LastName.Length > 0)
        {
            MyCompanyContext context = new MyCompanyContext();

            //insert
            if(employee.empid == 0)
             context.Employees.InsertOnSubmit(employee);
            else
            {
              //update goes here
            }

            context.SubmitChanges();


        }
        else 
          throw new BusinessRuleException("Employees must have first and last names");
     }
 }

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

    public ISingleResult<GetEmployeesAndManagersResult> LoadEmployeesAndManagers()
    {
        MyCompanyContext context = new MyCompanyContext();

        var emps = context.GetEmployeesAndManagers();

        return emps;
    }

على محمل الجد، كان LINQ إلى SQL يدعم بنية n-tier، راجع طريقة DataContext.Update

يشير بعض ما قرأته إلى أن منطق العمل يغلف DataContext - وبعبارة أخرى، فإنك تقوم بلف التحديث بالطريقة التي تقترحها.

الطريقة التقليدية التي أكتب بها كائنات الأعمال عادةً ما أقوم بتغليف "طرق التحميل" في BO أيضًا؛لذلك قد يكون لدي طريقة تسمى LoadEmployeesAndManagers والتي تُرجع قائمة بالموظفين ومديريهم المباشرين (هذا مثال مفتعل).ربما أنا فقط، ولكن في الواجهة الأمامية أفضل رؤية e.LoadEmployeesAndManagers()‎ بدلاً من بعض عبارات LINQ الطويلة.

على أي حال، باستخدام LINQ من المحتمل أن يبدو الأمر كما يلي (لم يتم التحقق من صحة بناء الجملة):

var emps = from e in Employees
                join m in Employees
                on e.ManagerEmpID equals m.EmpID
                select new
                          { e,
                            m.FullName
                          };

الآن، إذا فهمت الأمور بشكل صحيح، وإذا وضعت هذا في مكتبة الفصل على سبيل المثال واستدعته من الواجهة الأمامية، فإن الطريقة الوحيدة التي يمكنني من خلالها إرجاع هذا هي IEnumerable، لذلك أفقد صلاحيتي القوية في الكتابة.الطريقة الوحيدة التي سأتمكن من إرجاع كائن مكتوب بقوة هي إنشاء فئة الموظفين الخاصة بي (بالإضافة إلى حقل سلسلة لاسم المدير) وتعبئته من نتائج بيان LINQ إلى SQL الخاص بي ثم إرجاع ذلك.لكن هذا يبدو غير بديهي..ما الذي اشتراه لي LINQ to SQL بالضبط إذا كان علي أن أفعل كل ذلك؟

أعتقد أنني ربما أنظر إلى الأمور بطريقة خاطئة؛سيكون موضع تقدير أي تنوير.

"الطريقة الوحيدة التي يمكنني من خلالها إرجاع هذا هو IEnumerable، لذلك أفقد صلاحيتي القوية المكتوبة"

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

var emps = from e in Employees
            join m in Employees
            on e.ManagerEmpID equals m.EmpID
            select new Employee
                      { e,
                        m.FullName
                      };

والتي سوف ترجع IEnumerable.

هنا مقالة لقد كتبت عن هذا الموضوع.

Linq-to-sql هو ORM.ولا يؤثر على الطريقة التي تصمم بها تطبيقًا من فئة N.يمكنك استخدامه بنفس الطريقة التي تستخدم بها أي ORM آخر.

@ليامكلينان

والتي سوف ترجع IEnumerable....Linq-to-sql هو ORM.ولا يؤثر على الطريقة التي تصمم بها تطبيقًا من فئة N.يمكنك استخدامه بنفس الطريقة التي تستخدم بها أي ORM آخر.

ثم أعتقد أنني ما زلت في حيرة من أمري.نعم، Linq-to-Sql هو ORM؛ولكن بقدر ما أستطيع أن أقول إنني ما زلت أقوم بتوزيع كود الواجهة الأمامية الخاص بي باستخدام عبارات نوع SQL المضمنة (linq، وليس sql....ولكن ما زلت أشعر أنه يجب استخلاص هذا بعيدًا عن الواجهة الأمامية).

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

public class EmployeesDAL
{
    public IEnumerable LoadEmployeesAndManagers()
    {
            MyCompanyContext context = new MyCompanyContext();

            var emps = from e in context.Employees
            join m in context.Employees
            on e.ManagerEmpID equals m.EmpID
            select new
                      { e,
                        m.FullName
                      };

            return emps;
    }

}

من كود الواجهة الأمامية الخاص بي سأفعل شيئًا مثل هذا:

EmployeesDAL dal = new EmployeesDAL;
var emps = dal.LoadEmployeesAndManagers();

يؤدي هذا بالطبع إلى إرجاع IEnumerable؛لكن لا يمكنني استخدام هذا مثل أي ORM آخر كما تقول (ما لم أسيء الفهم بالطبع)، لأنني لا أستطيع القيام بذلك (مرة أخرى، هذا مثال مفتعل):

txtEmployeeName.Text = emps[0].FullName

هذا ما قصدته بـ "أفقد الخير المكتوب القوي". أعتقد أنني بدأت أتفق مع Crucible ؛أن LINQ-to-SQL لم يتم تصميمه ليتم استخدامه بهذه الطريقة.مرة أخرى، إذا لم أكن أرى الأشياء بشكل صحيح، فليدلني أحد على الطريق :)

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