راهنمای Net Core.
یافتن موقعیت جغرافیایی در HTML 5
My last post investigated ways to build a .NET Core desktop/console app with a web-rendered UI without bringing in the full weight of Electron. This seems to have interested a lot of people, so I decided to upgrade it to newer technologies and add cross-platform support.
The result is a little NuGet package called WebWindow that you can add to any .NET Core console app. It can open a native OS window (Windows/Mac/Linux) containing web-based UI, without your app having to bundle either Node or Chromium.
بررسی کارآیی Span در C# 7.2
معرفی موجودیت Person
در مثال این مطلب قصد داریم، معادل توابع بومی مخصوص SQL Server را که امکان کار با DateTime را مهیا میکنند، در EF Core تعریف کنیم. به همین جهت نیاز به موجودیتی داریم که دارای خاصیتی از این نوع باشد:
using System; namespace EFCoreDbFunctionsSample.Entities { public class Person { public int Id { get; set; } public string Name { get; set; } public DateTime AddDate { get; set; } } }
گزارشگیری بر اساس تعداد روز گذشتهی از ثبت نام
اکنون فرض کنید میخواهیم گزارشی را از تمام کاربرانی که در طی 10 روز قبل ثبت نام کردهاند، تهیه کنیم. اگر کوئری زیر را برای این منظور تهیه کنیم:
var usersInfo = context.People.Where(person => (DateTime.Now - person.AddDate).Days <= 10).ToList();
'The LINQ expression 'DbSet<Person>.Where(p => (DateTime.Now - p.AddDate).Days <= 10)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.'
SELECT [p].[Id], [p].[AddDate], [p].[Name] FROM [People] AS [p] WHERE DATEDIFF(Day, [p].[AddDate], GETDATE()) <= 10
روش تعریف تابع DATEDIFF سفارشی در EF Core
برای تعریف متد DateDiff مخصوص EF Core، ابتدا باید یک کلاس static را تعریف کرد و سپس تنها امضای این متد را، معادل امضای تابع توکار SQL Server تعریف کرد. این متد نیازی نیست تا پیاده سازی را داشته باشد. به همین جهت بدنهی آنرا صرفا با یک throw new InvalidOperationException مقدار دهی میکنیم. هدف از این متد، استفادهی از آن در LINQ Expressions است و قرار نیست به صورت مستقیمی بکار گرفته شود:
namespace EFCoreDbFunctionsSample.DataLayer { public enum SqlDateDiff { Year, Quarter, Month, DayOfYear, Day, Week, Hour, Minute, Second, MilliSecond, MicroSecond, NanoSecond } public static class SqlDbFunctionsExtensions { public static int SqlDateDiff(SqlDateDiff interval, DateTime initial, DateTime end) => throw new InvalidOperationException($"{nameof(SqlDateDiff)} method cannot be called from the client side."); public static readonly MethodInfo SqlDateDiffMethodInfo = typeof(SqlDbFunctionsExtensions) .GetRuntimeMethod( nameof(SqlDbFunctionsExtensions.SqlDateDiff), new[] { typeof(SqlDateDiff), typeof(DateTime), typeof(DateTime) } ); } }
روش معرفی تابع DATEDIFF سفارشی به EF Core
پس از تعریف امضای متد معادل DateDiff، اکنون نوبت به معرفی آن به EF Core است:
namespace EFCoreDbFunctionsSample.DataLayer { public class ApplicationDbContext : DbContext { // ... protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.HasDbFunction(SqlDbFunctionsExtensions.SqlDateDiffMethodInfo) .HasTranslation(args => { var parameters = args.ToArray(); var param0 = ((SqlConstantExpression)parameters[0]).Value.ToString(); return SqlFunctionExpression.Create("DATEDIFF", new[] { new SqlFragmentExpression(param0), // It should be written as DateDiff(day, ...) and not DateDiff(N'day', ...) . parameters[1], parameters[2] }, SqlDbFunctionsExtensions.SqlDateDiffMethodInfo.ReturnType, typeMapping: null); }); } } }
سپس توسط متد HasTranslation، مشخص میکنیم که این متد به چه نحوی قرار است به یک عبارت SQL ترجمه شود. پارامتر args ای که در اینجا در اختیار ما قرار میگیرد، دقیقا همان پارامترهای متد public static int SqlDateDiff(SqlDateDiff interval, DateTime initial, DateTime end) هستند که در این مثال خاص، شامل سه پارامتر میشوند. پارامترهای دوم و سوم آنرا به همان نحوی که دریافت میکنیم، به SqlFunctionExpression.Create ارسال خواهیم کرد. اما پارامتر اول را از نوع enum تعریف کردهایم و همچنین قرار نیست به صورت 'N'day و رشتهای به سمت بانک اطلاعاتی ارسال شود، بلکه باید به همان نحو اصلی آن (یعنی day)، در کوئری نهایی درج گردد، به همین جهت ابتدا Value آنرا استخراج کرده و سپس توسط SqlFragmentExpression عنوان میکنیم آنرا باید به همین نحو درج کرد.
پارامتر اول متد SqlFunctionExpression.Create، باید دقیقا معادل نام متد توکار مدنظر باشد. پارامتر دوم آن، لیست پارامترهای این تابع است. پارامتر سوم آن، نوع خروجی این تابع است که از طریق MethodInfo معادل، قابل استخراج است.
استفادهی از DbFunction سفارشی جدید در برنامه
پس از این تعاریف و معرفیها، اکنون میتوان متد سفارشی SqlDateDiff تهیه شده را به صورت مستقیمی در کوئریهای LINQ استفاده کرد تا قابلیت ترجمهی به SQL را پیدا کنند:
var sinceDays = 10; users = context.People.Where(person => SqlDbFunctionsExtensions.SqlDateDiff(SqlDateDiff.Day, person.AddDate, DateTime.Now) <= sinceDays).ToList(); /* SELECT [p].[Id], [p].[AddDate], [p].[Name] FROM [People] AS [p] WHERE DATEDIFF(Day, [p].[AddDate], GETDATE()) <= @__sinceDays_0 */
کدهای کامل این مثال را از اینجا میتوانید دریافت کنید: EFCoreDbFunctionsSample.zip
این کدها به همراه چند تابع سفارشی دیگر نیز هستند.
Microsoft's release notes highlights for Preview 3 include:
- Visual Studio now offers .NET Framework 4.7.2 development tools to supported platforms with 4.7.2 runtime included.
- We improved performance during project unload/reload and branch switching.
- With added support for Azure Functions, you now have a new target host in the Configure Continuous Delivery to Azure dialog.
- Git and TFS status now updates properly for external file changes in .NET Core projects.
- We added new productivity features, such as code cleanup, invert-if refactoring, Go to Enclosing Block, Multi-Caret support, and new keyboard profiles.
- C++ enhancements include Template IntelliSense, convert macro to constexpr lightbulbs, and experimental in-editor code analysis squiggles.
- You can now use cross-language debugging with Python 3.7.0rc1.
- Performance Profiling now offers the ability to pause/resume data collection and adds a new .NET Object Allocation Tracking tool.
- We included improvements for Android incremental builds in the Xamarinsupport for Xcode 9.4.
There's two ways to deploy a .NET Core application. There's FDD and SCD. Since TLAs (three letter acronyms) are stupid, that's Framework-dependent and Self-contained. When .NET Core is installed it ends up in C:\program files\dotnet on Windows, for example. In the "Shared" folder there's a bunch of .NET stuff that is, well, shared. There may be multiple folders, as you can see in my folder below. You can have many and multiple installs of .NET Core.