ابتدا مثال کامل ذیل را در نظر بگیرید:
using System; using System.Collections.Generic; using System.Data.Entity; using System.Data.Entity.Migrations; using System.Linq; using System.Linq.Expressions; namespace Sample { public abstract class BaseEntity { public int Id { set; get; } } public class Receipt : BaseEntity { public int TotalPrice { set; get; } } public class MyContext : DbContext { public DbSet<Receipt> Receipts { get; set; } } public class Configuration : DbMigrationsConfiguration<MyContext> { public Configuration() { AutomaticMigrationsEnabled = true; AutomaticMigrationDataLossAllowed = true; } protected override void Seed(MyContext context) { if (!context.Receipts.Any()) { for (int i = 0; i < 20; i++) { context.Receipts.Add(new Receipt { TotalPrice = i }); } } base.Seed(context); } } public static class EFUtils { public static IList<T> LoadEntities<T>(this DbContext ctx, Expression<Func<T, bool>> predicate) where T : class { return ctx.Set<T>().Where(predicate).ToList(); } public static IList<T> LoadData<T>(this DbContext ctx, Func<T, bool> predicate) where T : class { return ctx.Set<T>().Where(predicate).ToList(); } } public static class Test { public static void RunTests() { startDB(); using (var context = new MyContext()) { var list1 = context.LoadEntities<Receipt>(x => x.TotalPrice == 10); var list2 = context.LoadData<Receipt>(x => x.TotalPrice == 20); } } private static void startDB() { Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Configuration>()); // Forces initialization of database on model changes. using (var context = new MyContext()) { context.Database.Initialize(force: true); } } } }
نکته اصلی مورد بحث، کلاس کمکی EFUtils است که در آن دو متد الحاقی LoadEntities و LoadData تعریف شدهاند. در متد LoadEntities، امضای متد شامل Expression Func است و در متد LoadData فقط Func ذکر شده است.
در ادامه اگر برنامه را توسط فراخوانی متد RunTests اجرا کنیم، به نظر شما خروجی SQL حاصل از list1 و list2 چیست؟
احتمالا شاید عنوان کنید که هر دو یک خروجی SQL دارند (با توجه به اینکه بدنه متدهای LoadEntities و LoadData دقیقا/یا به نظر یکی هستند) اما یکی از پارامتر 10 استفاده میکند و دیگری از پارامتر 20. تفاوت دیگری ندارند.
اما ... اینطور نیست!
خروجی SQL متد LoadEntities در متد RunTests به صورت زیر است:
SELECT [Extent1].[Id] AS [Id], [Extent1].[TotalPrice] AS [TotalPrice] FROM [dbo].[Receipts] AS [Extent1] WHERE 10 = [Extent1].[TotalPrice]
SELECT [Extent1].[Id] AS [Id], [Extent1].[TotalPrice] AS [TotalPrice] FROM [dbo].[Receipts] AS [Extent1]
چرا؟
Func اشارهگری است به یک متد و Expression Func بیانگر ساختار درختی عبارت lambda نوشته شده است. این ساختار درختی صرفا بیان میکند که عبارت lambda منتسب، چه کاری را قرار است یا میتواند انجام دهد؛ بجای انجام واقعی آن.
public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate); public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);
بنابراین هرچند بدنه دو متد LoadEntities و LoadData به ظاهر یکی هستند، اما بر اساس نوع ورودی Where ایی که دریافت میکنند، اگر Expression Func باشد، EF فرصت آنالیز و ترجمه عبارت ورودی را خواهد یافت اما اگر Func باشد، ابتدا باید کل اطلاعات را به صورت یک لیست IEnumerable دریافت و سپس سمت کلاینت، خروجی نهایی را فیلتر کند.
اگر برنامه را اجرا کنید نهایتا هر دو لیست یک و دو، بر اساس شرط عنوان شده عمل خواهند کرد و فیلتر خواهند شد. اما در حالت اول این فیلتر شدن سمت بانک اطلاعاتی است و در حالت دوم کل اطلاعات بارگذاری شده و سپس سمت کاربر فیلتر میشود (که کارآیی پایینی دارد).
نتیجه گیری
به امضای متد Where ایی که در حال استفاده است دقت کنید. همینطور در مورد Sum ، Count و یا موارد مشابه دیگری که predicate قبول میکنند.
Url Routing در ASP.Net WebForms
The resource cannot be found. Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly. Requested URL: /Default.aspx
routes.MapPageRoute("Default", "", "~/default.aspx", False)
NET 7 Preview 5. منتشر شد
Today we released .NET 7 Preview 5. This preview of .NET 7 includes improvements to Generic Math which make the lives of API authors easier, a new Text Classification API for ML.NET that adds state-of-the-art deep learning techniques for natural language processing, various improvements to source code generators and a new Roslyn analyzer and fixer for RegexGenerator and multiple performance improvements in the areas of CodeGen, Observability, JSON serialization / deserialization and working with streams.
Vue.js 3.0 منتشر شد
Today we are proud to announce the official release of Vue.js 3.0 "One Piece". This new major version of the framework provides improved performance, smaller bundle sizes, better TypeScript integration, new APIs for tackling large scale use cases, and a solid foundation for long-term future iterations of the framework.
خواندنیهای 22 مرداد
اس کیوال سرور
الگوهای طراحی برنامه نویسی شیءگرا
امنیت
توسعه وب
دات نت فریم ورک
متفرقه
محیطهای مجتمع توسعه
ویندوز
Top Issues Fixed in Visual Studio 2019 version 16.4.6
- Miscompile, boolean condition deduced to be always true.
- Issue with loop unroll in Visual Studio 2019 compiler
- CL (VC v19.24) crashes when building in a docker volume folder
- CL (VC v19.22) crashes when it starts with the /ZI parameter in the docker container
- Compiling SSE intrinsics with MSVC compiler 19.20: compiled code yields incorrect results in one specific case
- C++ AMP code will not compile in Visual Studio 2019 16.3.1
- Sometimes coroutine_handle<>::destroy() resumes coroutine instead of destroying it.
- New Spectre mitigation options in C++ compiler: /Qspectre-load & /Qspectre-load-cf for speculative load hardening.
Security Advisory Notice
- CVE-2020-0793 & CVE-2020-0810 Diagnostics Hub Standard Collector Service Elevation of Privilege Vulnerability
- CVE-2020-0884 Spoofing vulnerability when creating Outlook Web -Add-in
- CVE-2020-0789 Visual Studio Extension Installer Service Denial of Service Vulnerability
کتابخانه 101
1) 101 will be maintained to minimize overlap with vanilla JS.
- 101 utils are made to work well with vanilla JS methods.
- 101 will only duplicate vanilla JS to provide functional programming paradigms or if the method is not available in a widely supported JS version (currently ES5).
- Underscore/lodash - duplicates a lot of ES5: forEach, map, reduce, filter, sort, and more.
2) No need for custom builds.
- With 101, import naturally, and what you use will be bundled.
- Each util method is a module that can be required require('101/<util>').
- Currently node/browserify is supported, I will add other module system support on request.
- Underscore/lodash is large, and you have to manually create custom builds when if you're trying to optimize for size.