استفاده از پروایدر SQLite در Entity Framework 7
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: دو دقیقه

Entity Framework در نگارش 7 خود از منابع داده‌ایی جدیدی پشتیبانی میکند(+) . یعنی از Windows Phone، Windows Store و همچنین ASP.NET 5 (اپلیکیشن‌هایی که از NET Core. استفاده می‌کنند) پشتیبانی خواهد کرد. در این نسخه از دیتابیس‌های non-relational نیز پشتیبانی می‌شود. پروایدر SQLite به صورت رسمی توسط تیم EF ارائه شده است که در ادامه نحوه‌ی استفاده از آن را در یک برنامه کنسول ساده بررسی خواهیم کرد.
کلاس‌های برنامه:
using Microsoft.Data.Entity;
using Microsoft.Data.Entity.Metadata;
using System.Collections.Generic;
using System.Linq;

namespace UsingEF7WithSQLite
{
    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }

        public List<Post> Posts { get; set; }
    }

    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }

        public int BlogId { get; set; }
        public Blog Blog { get; set; }
    }
}
خب تا اینجا مدل‌های برنامه را تعریف کردیم، قدم بعدی افزودن پکیج مربوط به پروایدر SQLite به پروژه است، با دستور زیر این پکیج را نصب می‌کنیم:
PM> Install-Package EntityFramework.SQLite –Pre
اکنون کلاس کانتکست برنامه را به صورت زیر تعریف می‌کنیم:
namespace UsingEF7SQLiteProvider
{
    public class BloggingContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }

        protected override void OnConfiguring(DbContextOptions builder)
        {
            builder.UseSQLite(@"Data Source=.\BloggingDatabae.db");
        }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            builder.Entity<Blog>()
                .OneToMany(b => b.Posts, p => p.Blog)
                .ForeignKey(p => p.BlogId);

            // The EF7 SQLite provider currently doesn't support generated values
            // so setting the keys to be generated from developer code
            builder.Entity<Blog>()
                .Property(b => b.BlogId)
                .GenerateValueOnAdd(false);

            builder.Entity<Post>()
                .Property(b => b.BlogId)
                .GenerateValueOnAdd(false);
        }
    }
}

کار را با بازنویسی متد OnConfiguration شروع می‌کنیم، در این قسمت باید به EF بگوئیم که می‌خواهیم از SQLite استفاده کنیم برای اینکار از یک Extension Method با نام UseSQLite و پاس دادن کانکشتن استرینگ به آن استفاده می‌کنیم.
نکته: پروایدر فعلی SQLite در حال حاضر از Generated values پشتیبانی نمی‌کند، برای این منظور باید درون متد OnModelCreating این قابلیت را غیرفعال کنیم.
اکنون می‌توانیم از طریق پاورشل نیوگت دیتابیس را ایجاد کنیم، برای اینکار باید پکیج زیر را به پروژه اضافه کنید:
Install-Package EntityFramework.Commands -Pre
سپس دستورات زیر را اجرا می‌کنیم:
Add-Migration MyFirstMigration
Apply-Migration
توسط دستور Apply-Migrate دیتابیس برای شما ایجاد خواهد شد. البته این دستور زمانی استفاده می‌شود که برنامه شما یک اپلیکیشن دسکتاپ باشد. اگر اپلیکیشن شما یک Windows Phone Application است باید در زمان اجرای برنامه این کد را بنویسید:
using (var db = new BloggingContext())
{
   db.Database.AsMigrationsEnabled().ApplyMigrations();
}
در نهایت می‌توانید با دستور زیر از کانتکست برنامه استفاده کرده و خروجی را مشاهده کنید:
using (var db = new Models.BloggingContext())
{
     db.Blogs.Add(new Models.Blog { Url = "https://www.dntips.ir" });
     db.SaveChanges();

     foreach (var item in db.Blogs)
     {
         Console.WriteLine(item.Url);
     }
}
Console.ReadLine();
  • #
    ‫۹ سال و ۱۰ ماه قبل، پنجشنبه ۴ دی ۱۳۹۳، ساعت ۲۳:۳۱
    سلام
    آیا شما خودتون از این پروایدر استفاده کردید؟
    وقتی من میخوام استفاده کنم و از طریق nuGet نصب کنم ارور میده.
    Install-Package : 'EntityFramework.SQLite' already has a dependency defined for 'EntityFramework.Migrations'.
    هیچ جوری نتونستم من نصبش کنم.
    • #
      ‫۹ سال و ۱۰ ماه قبل، جمعه ۵ دی ۱۳۹۳، ساعت ۰۳:۰۵
      - حتما نیاز است که از آخرین نگارش NuGet  استفاده کنید (NuGet 2.8.3 یا بالاتر).
      - کدهای کامل این مثال را از اینجا
      می‌توانید دریافت کنید.
  • #
    ‫۷ سال و ۵ ماه قبل، دوشنبه ۴ اردیبهشت ۱۳۹۶، ساعت ۱۸:۳۳
    به روز رسانی
    پیشنیازهای جدید کار با SQLite در فایل csproj آن برای VS 2017 و EF Core 1.1.1 به صورت ذیل هستند:
    <Project Sdk="Microsoft.NET.Sdk.Web">
      <ItemGroup>
        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="1.1.1" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.1" PrivateAssets="All" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="1.1.1" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="1.1.1" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="1.1.0" PrivateAssets="All" />
      </ItemGroup>
      <ItemGroup>
        <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.*" />
      </ItemGroup>
    </Project>
    • #
      ‫۱ ماه قبل، پنجشنبه ۱۸ مرداد ۱۴۰۳، ساعت ۱۸:۳۶

      یک نکته‌ی تکمیلی: اگر از SQLite به همراه بسته‌ی Microsoft.EntityFrameworkCore.Sqlite استفاده می‌کنید ... موتور SQLite آن، کمی قدیمی است. برای به‌روز رسانی موتور خود SQLite، نیاز است بسته‌ی SQLitePCLRaw.bundle_e_sqlite3 را هم به لیست ارجاعات برنامه‌ی خود اضافه کنید (به صورت صریح). برای مثال نگارش 8.0.7 به همراه EF-Core هر چند ارجاعی را به SQLitePCLRaw.bundle_e_sqlite3 دارد، اما از نگارش 2.1.6 آن استفاده می‌کند که مربوط به سال قبل است.

  • #
    ‫۵ روز قبل، دوشنبه ۹ مهر ۱۴۰۳، ساعت ۱۱:۵۹
    یک نکته‌ی تکمیلی: اگر از بانک اطلاعاتی SQLite استفاده می‌کنید، بهتر است از API غیرهمزمان EF-Core، برای کار با آن استفاده نکنید!

    توصیه عمومی جهت کار با بانک‌های اطلاعاتی، استفاده از API غیرهمزمان (async) آن‌ها برای انجام هر نوع عملیات I/O مرتبط با آن‌هاست؛ اما ... SQLite، هیچگونه I/O شبکه‌ای را به همراه ندارد و همچنین پشت صحنه‌ی پیاده سازی آن نیز مبتنی بر استفاده‌ی از متدهای متداول همزمان است. برای مثال SQLite جهت پیاده سازی حالت WAL آن، از تابع همزمان ()fsync استفاده می‌کند و عملا Asynchronous I/O ای در اینجا رخ نمی‌دهد. یکی از مهم‌ترین مزایای فعال بودن حالت WAL، امکان کار چند ریسمانی با بانک اطلاعاتی SQLite، بدون دریافت خطای «Error: database is locked» است که سبب می‌شود بتوان از این بانک اطلاعاتی، بدون بروز هیچ مشکلی، در برنامه‌های وب نیز استفاده کرد.
    یعنی API async آن (منظور API ای که توسط EF-Core ارائه می‌شود)، صرفا یک شبه محصور کننده‌ی blocking API همزمان آن است (یک async تقلبی!) و بیشتر سبب بروز یک سربار ناخواسته می‌شود؛ تا اینکه بهبود کارآیی خاصی را به همراه داشته باشد. به همین جهت بهتر است حین کار با بانک اطلاعاتی SQLite، از همان synchronous API معمولی و متداول آن استفاده شود.