نظرات مطالب
SQL Injection چیست؟
یعنی در صورت استفاده از linq هم باز این مشکل پا برجاست؟!
مطالب
breeze js به همراه ایجاد سایت آگهی قسمت اول
با قدرت گرفتن جاوا اسکریپت، نیازهایی مانند کوئری گرفتن در سمت کلاینت، کش کردن داده‌ها در سمت کلاینت، ردیابی تغییرات، اعتبارسنجی مدلها، ذخیره کردن گروهی از عملیات‌ها (Save Batch)، تعامل با Web Api .Net یا Node Js، قابلیت کار کردن با No Sql و... افزایش یافته است و تمام این کارها توسط breeze  امکان پذیر میباشد. breeze  با هر سرویس دهنده‌ای که بتواند از  طریق http و با فرمت json عملیات خود را انجام دهد، میتواند ارتباط برقرار کند.
breeze مطابق با استاندارد ECMAScript 5 نوشته شده‌است؛ از این‌رو بر روی اکثر مرورگرهای جدید به خوبی اجرا میشود.

  برای مرورگرهای قدیمی می‌توان کتابخانه es5-shim.js and es5-sham.js را قبل از تگ اسکریپت breeze js قرار داد.
در این قسمت به برخی از  توانایی های  breeze  اشاره کوتاهی میکنیم و در مقالات بعدی پیاده سازی آن‌را در قالب angular js /Web Api .net خواهیم داشت:
1- کوئری‌های breeze اکثر امکانات  linq را دارا می‌باشد؛ مانند شرطهای ساده، شرط‌های پیچیده، Sorting ،Paging،Projections  و Filter کردن برخی از پراپرتی‌ها که بسیار مشابه  linq میباشد:
var query = breeze.EntityQuery
           .from("Customers")
           .where("CompanyName", "startsWith", "A")
           .orderBy("CompanyName");
2- کوئری‌های breeze با promises عملیات خود را انجام میدهند:
var promise = manager.executeQuery(query)
              .then(querySucceeded)
              .fail(queryFailed);
* breeze مانند  entity framework  قابلیت ردیابی تغییرات را دارا میباشد:
if (manager.hasChanges()) {
    manager.saveChanges().then(saveSucceeded).fail(saveFailed);
}
// listen for any change to a customer 
customer.entityAspect.propertyChanged.subscribe(somethingHappened);
3- انقیاد داده‌ها با Angular / Knockout  / Backbone را دارا میباشد:
<!-- Angular template -->
<li data-ng-repeat="emp in employees">
    <label>{{emp.FirstName}}</label>
    <label>{{emp.LastName}}</label>
</li>
// bound to employees from query
manager.executeQuery(breeze.EntityQuery.from("Employees"))
       .then(function(data) { $scope.employees = data.results; });
4- درbreeze امکان  کوئری گرفتن به همراه entity‌های مرتبط وجود دارد:
/* Query with related entities using expand */
// query for orders of customers whose name begins "Alfreds"
// include their customers & child details & their detail products
breeze.EntityQuery.from("Orders")
   .where("Customer.CompanyName", "startsWith", "Alfreds")
   .expand("Customer, OrderDetails.Product")
   .using(manager)
   .execute().then(querySucceeded).fail(queryFailed);
5- در breeze  کوئری‌ها میتوانند از سرور و یا کش درخواست شوند:
// execute query asynchronously on the server
manager.executeQuery(query).then(querySuccess).fail(queryFail);
 
// execute query synchronously on local cache
var customers = manager.executeQueryLocally(query)
مطالب
اعمال توابع تجمعی بر روی چند ستون در Entity framework
فرض کنید که می‌خواهیم معادل کوئری زیر را که اعمال توابع تجمعی به چند ستون است،
 SELECT sum([Rating_TotalRating]), sum([Rating_TotalRaters]), sum([Rating_AverageRating]) FROM [BlogPosts]
در Entity framwork به کمک LINQ to Entities تهیه کنیم.
نکته‌ای که در اینجا وجود دارد، نبود گروه بندی (حداقل به ظاهر) در کوئری نوشته شده است. اما واقعیت این است که یک بانک اطلاعاتی به صورت ضمنی در مورد یک چنین کوئری‌هایی نیز گروه بندی را انجام می‌دهد. برای اینکار، کل رکوردهای مدنظر را یک گروه تصور می‌کند.
اگر سعی کنیم چنین کوئری را توسط عبارات LINQ ایجاد کنیم، در سعی اول به چنین کوئری خواهیم رسید که اصلا کامپایل نمی‌شود:
                context.BlogPost.Select(r =>
                                        new
                                        {
                                            Sum1 = r.Sum(x => x.RatingTotalRating),
                                            Sum2 = r.Sum(x => x.RatingTotalRaters),
                                            Sum3 = r.Sum(x => x.RatingAverageRating)
                                        }).FirstOrDefault();
بنابراین به نظر می‌رسد که شاید بهتر باشد از روش ذیل استفاده کنیم:
 var sum1 = context.BlogPost.Sum(x => x.RatingTotalRating);
var sum2 = context.BlogPost.Sum(x => x.RatingTotalRaters);
var sum2 = context.BlogPost.Sum(x => x.RatingAverageRating);
این روش کار می‌کند و نهایتا معادل نتایج کوئری اول را نیز حاصل خواهد کرد؛ اما با سه بار رفت و برگشت به بانک اطلاعاتی که اصلا بهینه نیست.

راه حل: ایجاد گروه بندی ضمنی SQL به صورت صریح در عبارات LINQ

                context.BlogPost
                       .GroupBy(dummyNumber => 0)
                       .Select(r =>
                                        new
                                        {
                                            Sum1 = r.Sum(x => x.RatingTotalRating),
                                            Sum2 = r.Sum(x => x.RatingTotalRaters),
                                            Sum3 = r.Sum(x => x.RatingAverageRating)
                                        }).FirstOrDefault();
در این کوئری جدید که بر اساس عدد ثابت صفر گروه بندی شده است، یک چنین SQL ایی تولید می‌شود:
SELECT TOP (1) 
                        [Extent1].[K1] AS [K1], 
                        Sum([Extent1].[A1]) AS [A1], 
                        Sum([Extent1].[A2]) AS [A2],
                        Sum([Extent1].[A3]) AS [A3]
                        FROM ( SELECT 
                            0 AS [K1], 
                            [Extent1].[RatingTotalRating] AS [A1], 
                            [Extent1].[RatingTotalRaters] AS [A2],
       [Extent1].[RatingAverageRating] AS [A3]
                            FROM [dbo].[BlogPosts] AS [Extent1]
                        )  AS [Extent1]
                        GROUP BY [K1]
ابتدا یک ستون فرضی با مقدار ثابت صفر به رکوردها اضافه می‌شود. سپس بر اساس این ستون فرضی، کلیه ردیف‌ها گروه بندی شده و در ادامه توابع تجمعی بر روی آن‌ها اعمال می‌گردند. به این ترتیب تعداد رفت و برگشت‌ها به بانک اطلاعاتی به همان یک مورد کاهش خواهد یافت.