مباحث migrations در EF Code first را مطالعه کنید، مسیر راه را پیدا خواهید کرد:
پاسخ به بازخوردهای پروژهها
using System; using System.Linq; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Data.Entity; using System.Data.Entity.Migrations; using System.Data.Entity.ModelConfiguration; namespace Sample { public class BlogPost { public int Id { set; get; } [StringLength(maximumLength: 450, MinimumLength = 1), Required] public string Title { set; get; } [MaxLength] public string Body { set; get; } public virtual ICollection<Tag> Tags { set; get; } // many-to-many public BlogPost() { Tags = new List<Tag>(); } } public class Tag { public int Id { set; get; } [StringLength(maximumLength: 450), Required] public string Name { set; get; } public virtual ICollection<BlogPost> BlogPosts { set; get; } // many-to-many public Tag() { BlogPosts = new List<BlogPost>(); } } public class MyContext : DbContext { public DbSet<BlogPost> BlogPosts { get; set; } public DbSet<Tag> Tags { get; set; } } public class Configuration : DbMigrationsConfiguration<MyContext> { public Configuration() { AutomaticMigrationsEnabled = true; AutomaticMigrationDataLossAllowed = true; } protected override void Seed(MyContext context) { var tag1 = new Tag { Name = "Tag1" }; context.Tags.Add(tag1); var post1 = new BlogPost { Title = "Title...1", Body = "Body...1" }; context.BlogPosts.Add(post1); post1.Tags.Add(tag1); base.Seed(context); } } public static class Test { public static void RunTests() { Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Configuration>()); using (var ctx = new MyContext()) { var post1 = ctx.BlogPosts.Find(1); if (post1 != null) { Console.WriteLine(post1.Title); } } } } }
public class TagMap : EntityTypeConfiguration<Tag> { public TagMap() { this.HasMany(x => x.BlogPosts) .WithMany(x => x.Tags) .Map(map => { map.MapLeftKey("TagId"); map.MapRightKey("BlogPostId"); map.ToTable("BlogPostsJoinTags"); }); } } public class MyContext : DbContext { public DbSet<BlogPost> BlogPosts { get; set; } public DbSet<Tag> Tags { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new TagMap()); base.OnModelCreating(modelBuilder); } }
using (var ctx = new MyContext()) { var post1 = ctx.BlogPosts.Find(1); if (post1 != null) { Console.WriteLine(post1.Title); foreach (var tag in post1.Tags.ToList()) post1.Tags.Remove(tag); ctx.SaveChanges(); } }
var post1 = ctx.BlogPosts.Find(1); if (post1 != null) { ctx.BlogPosts.Remove(post1); ctx.SaveChanges(); }
var post1 = ctx.BlogPosts.Find(1); if (post1 != null) { var tag2 = new Tag { Name = "Tag2" }; post1.Tags.Add(tag2); ctx.SaveChanges(); }
//نام تگهای دریافتی از کاربر var tagsList = new[] { "Tag1", "Tag2", "Tag3" }; //بارگذاری یک مطلب به همراه تگهای آن var post1 = ctx.BlogPosts.Include(x => x.Tags).FirstOrDefault(x => x.Id == 1); if (post1 != null) { //ابتدا کلیه تگهای موجود را حذف خواهیم کرد if (post1.Tags != null && post1.Tags.Any()) post1.Tags.Clear(); //سپس در طی فقط یک کوئری بررسی میکنیم کدامیک از موارد ارسالی موجود هستند var listOfActualTags = ctx.Tags.Where(x => tagsList.Contains(x.Name)).ToList(); var listOfActualTagNames = listOfActualTags.Select(x => x.Name.ToLower()).ToList(); //فقط موارد جدید به تگها و ارتباطات موجود اضافه میشوند foreach (var tag in tagsList) { if (!listOfActualTagNames.Contains(tag.ToLowerInvariant().Trim())) { ctx.Tags.Add(new Tag { Name = tag.Trim() }); } } ctx.SaveChanges(); // ثبت موارد جدید //موارد قبلی هم حفظ میشوند foreach (var item in listOfActualTags) { post1.Tags.Add(item); } ctx.SaveChanges(); }
SELECT [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name] FROM [dbo].[Tags] AS [Extent1] WHERE [Extent1].[Name] IN (N'Tag1',N'Tag2',N'Tag3')
ctx.BlogPosts.Where(p => p.Id == 1).Include(p => p.Tags).FirstOrDefault()
var posts = from p in ctx.BlogPosts from t in p.Tags where t.Name == "Tag1" select p;
var posts = ctx.Tags.Where(x => x.Name == "Tag1").SelectMany(x => x.BlogPosts);
namespace BlazorWasmSQLite.Models; public class Car { public int Id { get; set; } public string Brand { get; set; } public int Price { get; set; } }
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) { } }
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly"> <ItemGroup> <!-- EF Core and Sqlite --> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.1" /> </ItemGroup> </Project>
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();
@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(); } }
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()
$ git clone https://github.com/cloudmeter/sqlite $ cd sqlite $ emcc sqlite3.c -shared -o 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>
using (var db = new BloggingContext()) { var blog = new Blog { Url = "http://sample.com" }; db.Blogs.Add(blog); db.SaveChanges(); }
using (var db = new BloggingContext()) { var blog = db.Blogs.First(); blog.Url = "http://sample.com/blog"; db.SaveChanges(); }
using (var db = new BloggingContext()) { var blog = db.Blogs.First(); db.Blogs.Remove(blog); db.SaveChanges(); }
using (var context = new BloggingContext()) { var blog = context.Blogs .Select(b => new { Blog = b, Posts = b.Posts.Count() }); }
using (var context = new BloggingContext()) { var blog = context.Blogs .Select(b => new { Id = b.BlogId, Url = b.Url }); }
using (var context = new BloggingContext()) { var blogs = context.Blogs.AsNoTracking().ToList(); }
using (var context = new BloggingContext()) { context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
using (var context = new BloggingContext()) { var blog = context.Blogs.First(); var post = new Post { Title = "Intro to EF Core" }; blog.Posts.Add(post); context.SaveChanges(); }
using (var context = new BloggingContext()) { var blog = new Blog { Url = "http://blogs.msdn.com/visualstudio" }; var post = context.Posts.First(); blog.Posts.Add(post); context.SaveChanges(); }
var blog = new Blog { Id = 2, Url = "https://www.dntips.ir" }; context.Blog.Attach(blog); context.SaveChanges();
var blog = new Blog { Id = 2, Url = "https://www.dntips.ir" }; context.Entry(blog).State = EntityState.Modified ; context.SaveChanges();
var blog = new Blog { Id = 2, Url = "https://www.dntips.ir" }; context.Update(blog); context.SaveChanges();
context.ChangeTracker.TrackGraph(blog, e => e.Entry.State = EntityState.Added);
public class BaseEntity { public int Id { set; get; } public DateTime? DateAdded { set; get; } public DateTime? DateUpdated { set; get; } }
public class Person : BaseEntity { public string FirstName { get; set; } public string LastName { get; set; } }
public class ApplicationDbContext : DbContext { // same as before public override int SaveChanges() { this.ChangeTracker.DetectChanges(); var modifiedEntries = this.ChangeTracker .Entries<BaseEntity>() .Where(x => x.State == EntityState.Modified); foreach (var modifiedEntry in modifiedEntries) { modifiedEntry.Entity.DateUpdated = DateTime.UtcNow; } var addedEntries = this.ChangeTracker .Entries<BaseEntity>() .Where(x => x.State == EntityState.Added); foreach (var addedEntry in addedEntries) { addedEntry.Entity.DateAdded = DateTime.UtcNow; } return base.SaveChanges(); } }
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>().Property<DateTime>("DateAdded");
var blogs = context.Blogs.OrderBy(b => EF.Property<DateTime>(b, "DateAdded"));
context.Entry(myBlog).Property("DateAdded").CurrentValue = DateTime.Now;
foreach (var addedEntry in addedEntries) { addedEntry.Property("DateAdded").CurrentValue = DateTime.UtcNow; }
HibernatingRhinos.Profiler.Appender.EntityFramework.EntityFrameworkProfiler.Initialize();
using System.Collections.Generic;
namespace EF_Sample06.Models
{
public class Department
{
public int DepartmentId { get; set; }
public string Name { get; set; }
//Creates Employee navigation property for Lazy Loading (1:many)
public virtual ICollection<Employee> Employees { get; set; }
}
}
namespace EF_Sample06.Models
{
public class Employee
{
public int EmployeeId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
//Creates Department navigation property for Lazy Loading
public virtual Department Department { get; set; }
}
}
using System.Data.Entity;
using EF_Sample06.Models;
namespace EF_Sample06.DataLayer
{
public class Sample06Context : DbContext
{
public DbSet<Department> Departments { set; get; }
public DbSet<Employee> Employees { set; get; }
}
}
using System.Collections.Generic;
using System.Data.Entity.Migrations;
using EF_Sample06.Models;
namespace EF_Sample06.DataLayer
{
public class Configuration : DbMigrationsConfiguration<Sample06Context>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
protected override void Seed(Sample06Context context)
{
var employee1 = new Employee { FirstName = "f name1", LastName = "l name1" };
var employee2 = new Employee { FirstName = "f name2", LastName = "l name2" };
var employee3 = new Employee { FirstName = "f name3", LastName = "l name3" };
var employee4 = new Employee { FirstName = "f name4", LastName = "l name4" };
var dept1 = new Department { Name = "dept 1", Employees = new List<Employee> { employee1, employee2 } };
var dept2 = new Department { Name = "dept 2", Employees = new List<Employee> { employee3 } };
var dept3 = new Department { Name = "dept 3", Employees = new List<Employee> { employee4 } };
context.Departments.Add(dept1);
context.Departments.Add(dept2);
context.Departments.Add(dept3);
base.Seed(context);
}
}
}
void ExportMappings(DbContext context, string edmxFile)
{
var settings = new XmlWriterSettings { Indent = true };
using (XmlWriter writer = XmlWriter.Create(edmxFile, settings))
{
System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(context, writer);
}
}
using (var db = new Sample06Context())
{
ExportMappings(db, "mappings.edmx");
}
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using EF_Sample06.DataLayer;
using EF_Sample06.Models;
namespace EF_Sample06
{
class Program
{
static IList<Employee> FindEmployees(string fName, string lName, bool byName, bool byLName)
{
using (var db = new Sample06Context())
{
IQueryable<Employee> query = db.Employees.AsQueryable();
if (byLName)
{
query = query.Where(x => x.LastName == lName);
}
if (byName)
{
query = query.Where(x => x.FirstName == fName);
}
return query.ToList();
}
}
static void Main(string[] args)
{
// note: remove this line if you received : create database is not supported by this provider.
HibernatingRhinos.Profiler.Appender.EntityFramework.EntityFrameworkProfiler.Initialize();
Database.SetInitializer(new MigrateDatabaseToLatestVersion<Sample06Context, Configuration>());
var list = FindEmployees("f name1", "l name1", true, true);
foreach (var item in list)
{
Console.WriteLine(item.FirstName);
}
}
}
}
var list = FindEmployees("f name1", "l name1", true, true);
SELECT [Extent1].[EmployeeId] AS [EmployeeId],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
[Extent1].[Department_DepartmentId] AS [Department_DepartmentId]
FROM [dbo].[Employees] AS [Extent1]
WHERE ([Extent1].[LastName] = 'l name1' /* @p__linq__0 */)
AND ([Extent1].[FirstName] = 'f name1' /* @p__linq__1 */)
using (var db = new Sample06Context())
{
var dept1 = db.Departments.Find(1);
if (dept1 != null)
{
Console.WriteLine(dept1.Name);
foreach (var item in dept1.Employees)
{
Console.WriteLine(item.FirstName);
}
}
}
SELECT [Limit1].[DepartmentId] AS [DepartmentId],
[Limit1].[Name] AS [Name]
FROM (SELECT TOP (2) [Extent1].[DepartmentId] AS [DepartmentId],
[Extent1].[Name] AS [Name]
FROM [dbo].[Departments] AS [Extent1]
WHERE [Extent1].[DepartmentId] = 1 /* @p0 */) AS [Limit1]
SELECT [Extent1].[EmployeeId] AS [EmployeeId],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
[Extent1].[Department_DepartmentId] AS [Department_DepartmentId]
FROM [dbo].[Employees] AS [Extent1]
WHERE ([Extent1].[Department_DepartmentId] IS NOT NULL)
AND ([Extent1].[Department_DepartmentId] = 1 /* @EntityKeyValue1 */)
using (var db = new Sample06Context())
{
foreach (var dept in db.Departments)
{
Console.WriteLine(dept.Name);
foreach (var item in dept.Employees)
{
Console.WriteLine(item.FirstName);
}
}
}
There is already an open DataReader associated with this Command which must be closed first
<connectionStrings>
<clear/>
<add
name="Sample06Context"
connectionString="Data Source=(local);Initial Catalog=testdb2012;Integrated Security = true;MultipleActiveResultSets=True;"
providerName="System.Data.SqlClient"
/>
</connectionStrings>
using (var db = new Sample06Context())
{
foreach (var dept in db.Departments.Include(x => x.Employees))
{
Console.WriteLine(dept.Name);
foreach (var item in dept.Employees)
{
Console.WriteLine(item.FirstName);
}
}
}
SELECT [Project1].[DepartmentId] AS [DepartmentId],
[Project1].[Name] AS [Name],
[Project1].[C1] AS [C1],
[Project1].[EmployeeId] AS [EmployeeId],
[Project1].[FirstName] AS [FirstName],
[Project1].[LastName] AS [LastName],
[Project1].[Department_DepartmentId] AS [Department_DepartmentId]
FROM (SELECT [Extent1].[DepartmentId] AS [DepartmentId],
[Extent1].[Name] AS [Name],
[Extent2].[EmployeeId] AS [EmployeeId],
[Extent2].[FirstName] AS [FirstName],
[Extent2].[LastName] AS [LastName],
[Extent2].[Department_DepartmentId] AS [Department_DepartmentId],
CASE
WHEN ([Extent2].[EmployeeId] IS NULL) THEN CAST(NULL AS int)
ELSE 1
END AS [C1]
FROM [dbo].[Departments] AS [Extent1]
LEFT OUTER JOIN [dbo].[Employees] AS [Extent2]
ON [Extent1].[DepartmentId] = [Extent2].[Department_DepartmentId]) AS [Project1]
ORDER BY [Project1].[DepartmentId] ASC,
[Project1].[C1] ASC
public class Sample06Context : DbContext
{
public Sample06Context()
{
this.Configuration.LazyLoadingEnabled = false;
}
public class Department
{
public int DepartmentId { get; set; }
public string Name { get; set; }
public ICollection<Employee> Employees { get; set; }
public Department()
{
Employees = new HashSet<Employee>();
}
}