نظرات مطالب
استفاده‌ی گسترده از DateTimeOffset در NET Core.
یک نکته‌ی تکمیلی: تبدیلگرهای DateTimeOffset برای بانک‌های اطلاعاتی که از آن پشتیبانی نمی‌کنند

خود EF Core به همراه تبدیلگرهای توکار زیر برای کار ساده‌تر با DateTimeOffset در بانک اطلاعاتی‌هایی مانند SQLite و یا MySQL است:

DateTimeOffsetToBinaryConverter - DateTimeOffset to binary-encoded 64-bit value (stores it as a long, slight reduction in precision)

DateTimeOffsetToBytesConverter - DateTimeOffset to byte array (stores it as a 12 byte array, 8 bytes for time, 4 bytes for offset. Full precision.)

DateTimeOffsetToStringConverter - DateTimeOffset to string (ISO 8601 string including timezone) 

و برای مثال می‌توان آن‌ها را به صورت زیر و سراسری، به سیستم معرفی کرد:
protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);

    if (Database.ProviderName == "Microsoft.EntityFrameworkCore.Sqlite")
    {
        // SQLite does not have proper support for DateTimeOffset via Entity Framework Core, see the limitations
        // here: https://docs.microsoft.com/en-us/ef/core/providers/sqlite/limitations#query-limitations
        // To work around this, when the Sqlite database provider is used, all model properties of type DateTimeOffset
        // use the DateTimeOffsetToBinaryConverter
        // Based on: https://github.com/aspnet/EntityFrameworkCore/issues/10784#issuecomment-415769754
        // This only supports millisecond precision, but should be sufficient for most use cases.
        foreach (var entityType in builder.Model.GetEntityTypes())
        {
            var properties = entityType.ClrType.GetProperties().Where(p => p.PropertyType == typeof(DateTimeOffset));
            foreach (var property in properties)
            {
                builder
                    .Entity(entityType.Name)
                    .Property(property.Name)
                    .HasConversion(new DateTimeOffsetToBinaryConverter());
            }
        }
    }
}
اشتراک‌ها
دوره 3 ساعته NET MAUI.

.NET MAUI Course for Beginners – Create Cross-Platform Apps with C#

Learn how to use .NET MAUI for native cross-platform desktop and mobile development! You will learn the essentials of building mobile applications with .NET MAUI and C# while creating a Contacts app.

⭐️ Contents ⭐️
⌨️ (0:00:00) Introduction
⌨️ (0:03:42) What is .Net Maui - .Net Maui vs Xamarin Forms
⌨️ (0:06:52) Prepare Development Environment _ Create first project
⌨️ (0:12:29) Project Structure
⌨️ (0:20:28) Three elements of stateful .Net Maui
⌨️ (0:23:51) Page, Layout _ View, Namespaces
⌨️ (0:33:02) URL based navigation
⌨️ (0:51:10) Basics of ListView and Data Binding
⌨️ (1:05:58) Events Handling of ListView
⌨️ (1:16:54) Parameters in URL based Navigation _ Static Repository
⌨️ (1:35:35) Stacklayout for Edit Contact page
⌨️ (1:52:47) View Contact Details _ Update Contact
⌨️ (2:06:40) Observable Collection
⌨️ (2:14:58) Field Validation with .Net Maui CommunityToolkit
⌨️ (2:27:08) Reusable Control
⌨️ (2:40:37) Grid Layout and  Use reusable control
⌨️ (2:53:23) ContextActions _ MenuItems in ListView
⌨️ (3:03:44) SearchBar in .NetMaui 

دوره 3 ساعته NET MAUI.
مطالب
امکان استفاده از کتابخانه‌های native در Blazor WASM 6x
کتابخانه‌‌های بسیاری هستند که به زبان‌های C ، C++ ، Rust و امثال آن تهیه شده‌اند. دات نت 6، قابلیت جدید استفاده‌ی از این نوع کتابخانه‌ها را بدون نیاز به تبدیل کدهای آن‌ها به #C، به برنامه‌های سمت کلاینت Blazor Web Assembly اضافه کرده که در این مطلب، نمونه‌ای از آن‌را با استفاده از بانک اطلاعاتی SQLite در برنامه‌های Blazor WASM 6x، بررسی خواهیم کرد. یعنی یک برنامه‌ی SPA سمت کلاینت که بدون نیاز به سرور و Web API، تنها با استفاده از EF-Core و بانک اطلاعاتی بومی SQLite می‌تواند اطلاعات مورد نیاز خود را ثبت و یا بازیابی کند (همه چیز داخل مرورگر رخ می‌دهد).


ایجاد یک پروژه‌ی Blazor WASM جدید

یک پوشه‌ی جدید دلخواه را به نام BlazorWasmSQLite ایجاد کرده و با اجرای دستور dotnet new blazorwasm، یک پروژه‌ی Blazor Web Assembly خالی جدید را در آن آغاز می‌کنیم. همانطور که از دستور نیز مشخص است، این پروژه از نوع hosted که به همراه Web API هم هست، نمی‌باشد.


افزودن Context و مدل EF-Core به برنامه

مدل برنامه به صورت زیر در پوشه‌ی Models آن قرار می‌گیرد:
namespace BlazorWasmSQLite.Models;

public class Car
{
  public int Id { get; set; }

  public string Brand { get; set; }

  public  int Price { get; set; }
}
و Context ای که آن‌را در معرض دید قرار می‌دهد، به صورت زیر تعریف خواهد شد:
using Microsoft.EntityFrameworkCore;
using BlazorWasmSQLite.Models;

namespace BlazorWasmSQLite.Data;

public class ClientSideDbContext : DbContext
{
  public DbSet<Car> Cars { get; set; } = default!;

  public ClientSideDbContext(DbContextOptions<ClientSideDbContext> options) :
    base(options)
  {
  }
}
همچنین چون می‌خواهیم از بانک اطلاعاتی SQLite استفاده کنیم، وابستگی زیر را به فایل csproj برنامه اضافه می‌کنیم:
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
  <ItemGroup>
    <!-- EF Core and Sqlite -->
    <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.1" />
  </ItemGroup>
</Project>
سپس این Context را به نحو زیر به فایل Program.cs معرفی می‌کنیم:
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using BlazorWasmSQLite;
using Microsoft.EntityFrameworkCore;
using BlazorWasmSQLite.Data;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

// Sets up EF Core with Sqlite
builder.Services.AddDbContextFactory<ClientSideDbContext>(options =>
      options
        .UseSqlite($"Filename=DemoData.db")
        .EnableSensitiveDataLogging());

await builder.Build().RunAsync();
در مورد علت استفاده‌ی از AddDbContextFactory و نکات مرتبط با آن، به مطلب «نکات ویژه‌ی کار با EF-Core در برنامه‌های Blazor Server» مراجعه نمائید.


ثبت تعدادی رکورد در بانک اطلاعاتی

در ادامه سعی می‌کنیم در فایل Index.razor، تعدادی رکورد را به بانک اطلاعاتی اضافه کنیم:
@page "/"

@using Microsoft.Data.Sqlite
@using Microsoft.EntityFrameworkCore
@using BlazorWasmSQLite.Data
@using BlazorWasmSQLite.Models


<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />

@code {
  [Inject]
  private IDbContextFactory<ClientSideDbContext> _dbContextFactory { get; set; } = default!;

  protected override async Task OnInitializedAsync()
  {
    await using var db = await _dbContextFactory.CreateDbContextAsync();
    await db.Database.EnsureCreatedAsync();

    // create seed data
    if (!db.Cars.Any())
    {
      var cars = new[]
      {
        new Car { Brand = "Audi", Price = 21000 },
        new Car { Brand = "Volvo", Price = 11000 },
        new Car { Brand = "Range Rover", Price = 135000 },
        new Car { Brand = "Ford", Price = 8995 }
      };

      await db.Cars.AddRangeAsync(cars);
      await db.SaveChangesAsync();
    }

    await base.OnInitializedAsync();
  }
}
در این مثال سعی شده‌است ساده‌ترین حالت ممکن کار با EF-Core در پیش گرفته شود؛ چون هدف اصلی آن، دسترسی به SQLite است.


اولین سعی در اجرای برنامه

در ادامه سعی می‌کنیم تا برنامه را اجرا کنیم. با خطای زیر متوقف خواهیم شد:
crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] Unhandled exception rendering component:
The type initializer for 'Microsoft.Data.Sqlite.SqliteConnection' threw an exception. System.TypeInitializationException:
The type initializer for 'Microsoft.Data.Sqlite.SqliteConnection' threw an exception. ---> System.Reflection.TargetInvocationException:
Exception has been thrown by the target of an invocation. ---> System.DllNotFoundException: e_sqlite3 at
SQLitePCL.SQLite3Provider_e_sqlite3.SQLitePCL.ISQLite3Provider.sqlite3_libversion_number()
عنوان می‌کند که فایل‌های بانک اطلاعاتی SQLite به همراه EF-Core را نمی‌تواند پیدا کند. یا به عبارتی هر DLL بومی را نمی‌توان داخل مرورگر اجرا کرد.


رفع مشکل کار با SQLite با کامپایل ویژه‌ی آن

برای دسترسی به کدهای native در Blazor WASM و مرورگر، باید آن‌ها را توسط کامپایلر emcc به صورت زیر کامپایل کرد:
$ git clone https://github.com/cloudmeter/sqlite
$ cd sqlite
$ emcc sqlite3.c -shared -o e_sqlite3.o
در اینجا هر نوع فایل portable native code با فرمت‌های o. یا object files، .a و یا archive files و یا .bc یا bitcode و یا .wasm یا Standalone WebAssembly modules توسط Blazor wasm قابل استفاده هستند که در مثال فوق نمونه‌ی object files آن‌ها توسط کامپایلر تولید می‌شود.
مرحله‌ی بعد، معرفی این object file تولید شده به برنامه است. برای اینکار ابتدا باید dotnet workload install wasm-tools را نصب کرد (مهم). سپس به فایل csproj برنامه مراجعه کرده و فایل e_sqlite3.o را به آن معرفی می‌کنیم:
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
  <ItemGroup>
    <!-- EF Core and Sqlite -->
    <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.1" />
    <NativeFileReference Include="Data\e_sqlite3.o" />
  </ItemGroup>
</Project>
در اینجا فرض شده‌است که فایل o. حاصل، در پوشه‌ی data قرار دارد. این نوع فایل‌ها توسط NativeFileReferenceها به برنامه معرفی می‌شوند.


سعی در اجرای مجدد برنامه

پس از نصب wasm-tools و ذکر NativeFileReference فوق، اکنون اگر برنامه را اجرا کنیم، برنامه بدون مشکل اجرا خواهد شد:



کدهای کامل این مطلب را از اینجا می‌توانید دریافت کنید: BlazorWasmSQLite.zip
اشتراک‌ها
سری آموزشی Blazor Hybrid

Blazor Hybrid for Beginners
Join James Montemagno as he takes you on a journey of building your first Hybrid applications across iOS, Android, Mac, Windows, and Web with ASP.NET Core, Blazor, Blazor Hybrid, and .NET MAUI!  You will learn how to use Blazor Hybrid to blend desktop and mobile native client frameworks with .NET and Blazor.
In a Blazor Hybrid app, Razor components run natively on the device. Components render to an embedded Web View control through a local interop channel. Components don't run in the browser, and WebAssembly isn't involved. Razor components load and execute code quickly, and components have full access to the native capabilities of the device through the .NET platform. Component styles rendered in a Web View are platform dependent and may require you to account for rendering differences across platforms using custom stylesheets.
Blazor Hybrid support is built into the .NET Multi-platform App UI (.NET MAUI) framework. .NET MAUI includes the BlazorWebView control that permits rendering Razor components into an embedded Web View. By using .NET MAUI and Blazor together, you can reuse one set of web UI components across mobile, desktop, and web.
 

سری آموزشی Blazor Hybrid
اشتراک‌ها
دوره‌های دات نت در Microsoft Learn

Microsoft Learn For .NET
Free. Cross-platform. Open source.
Learn how to build apps across multiple platforms with programming languages like C#, F#, and Visual Basic. Supported on Windows, Linux, and macOS, get started developing your next project with .NET today. 

دوره‌های دات نت در Microsoft Learn
اشتراک‌ها
توسعه ASP.NET Core Web Api CRUD در دات نت 7

.NET 7 💥 - ASP.NET Core Web Api CRUD, Repository Pattern, SQLite & Automapper
In this video we will be going to be create a full .NET WebApi  with Automapper, SQLite and utilising the Repository Pattern
 

توسعه ASP.NET Core Web Api CRUD در دات نت 7