代码改变世界

EntityFrameworkCore 学习笔记之示例一

  音乐让我说  阅读(583)  评论(0编辑  收藏  举报

直接贴代码了:

1. Program.cs

复制代码
using Microsoft.EntityFrameworkCore;
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;

namespace LazyLoading
{
    class Program
    {
        static async Task Main()
        {
            var container = AppServices.Instance.Container;
            var booksService = container.GetRequiredService<BooksService>();
            await booksService.CreateDatabaseAsync();
            booksService.GetBooksWithLazyLoading();
            booksService.GetBooksWithEagerLoading();
            booksService.GetBooksWithExplicitLoading();
            await booksService.DeleteDatabaseAsync();
        }
    }
}
复制代码

 

2. Book

复制代码
using System.Collections.Generic;

namespace LazyLoading
{
    public class Book
    {
        public Book(int bookId, string title) => (BookId, Title) = (bookId, title);

        public Book(int bookId, string title, string publisher) => (BookId, Title, Publisher) = (bookId, title, publisher);

        public int BookId { get; set; }
        public string Title { get; set; }
        public string? Publisher { get; set; }
        public virtual ICollection<Chapter> Chapters { get; } = new List<Chapter>();
        public int? AuthorId { get; set; }
        public int? ReviewerId { get; set; }
        public int? EditorId { get; set; }

        public virtual User? Author { get; set; }
        public virtual User? Reviewer { get; set; }
        public virtual User? Editor { get; set; }
    }
}
复制代码

3. BookConfiguration

复制代码
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace LazyLoading
{
    internal class BookConfiguration : IEntityTypeConfiguration<Book>
    {
        public void Configure(EntityTypeBuilder<Book> builder)
        {
            builder.HasMany(b => b.Chapters)
                .WithOne(c => c.Book)
                .OnDelete(DeleteBehavior.Cascade);
            builder.HasOne(b => b.Author)
                .WithMany(a => a.WrittenBooks)
                .HasForeignKey(b => b.AuthorId)
                .OnDelete(DeleteBehavior.Restrict);
            builder.HasOne(b => b.Reviewer)
                .WithMany(r => r.ReviewedBooks)
                .HasForeignKey(b => b.ReviewerId)
                .OnDelete(DeleteBehavior.Restrict);
            builder.HasOne(b => b.Editor)
                .WithMany(e => e.EditedBooks)
                .HasForeignKey(e => e.EditorId)
                .OnDelete(DeleteBehavior.Restrict);
            builder.Property(b => b.Title)
                .HasMaxLength(50)
                .IsRequired();
            builder.Property(b => b.Publisher)
                .HasMaxLength(30)
                .IsRequired(false);
        }
    }
}
复制代码

 

4. User

复制代码
using System.Collections.Generic;

namespace LazyLoading
{
    public class User
    {
        public User(int userId, string name) => (UserId, Name) = (userId, name);

        public int UserId { get; set; }
        public string Name { get; set; }
        public virtual List<Book> WrittenBooks { get; } = new List<Book>();
        public virtual List<Book> ReviewedBooks { get; } = new List<Book>();
        public virtual List<Book> EditedBooks { get; } = new List<Book>();
    }
}
复制代码

 

5. UserConfiguration

复制代码
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace LazyLoading
{
    internal class UserConfiguration : IEntityTypeConfiguration<User>
    {
        public void Configure(EntityTypeBuilder<User> builder)
        {
            builder.HasMany(a => a.WrittenBooks)
                .WithOne(nameof(Book.Author))
                .OnDelete(DeleteBehavior.Restrict);
            builder.HasMany(r => r.ReviewedBooks)
                .WithOne(nameof(Book.Reviewer))
                .OnDelete(DeleteBehavior.Restrict);
            builder.HasMany(e => e.EditedBooks)
                .WithOne(nameof(Book.Editor))
                .OnDelete(DeleteBehavior.Restrict);
        }
    }
}
复制代码

 

6. Chapter

复制代码
namespace LazyLoading
{
    public class Chapter
    {
        public Chapter(int chapterId, int number, string title) => 
            (ChapterId, Number, Title) = (chapterId, number, title);

        public int ChapterId { get; set; }
        public int Number { get; set; }
        public string Title { get; set; }
        public int BookId { get; set; }
        public virtual Book? Book { get; set; }
    }
}
复制代码

 

 

7. ChapterConfiguration

复制代码
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace LazyLoading
{
    internal class ChapterConfiguration : IEntityTypeConfiguration<Chapter>
    {
        public void Configure(EntityTypeBuilder<Chapter> builder)
        {
            builder.HasOne(c => c.Book)
                .WithMany(b => b.Chapters)
                .HasForeignKey(c => c.BookId);
        }
    }
}
复制代码

 

 

8. BooksContext

复制代码
using Microsoft.EntityFrameworkCore;

#nullable disable

namespace LazyLoading
{
    public class BooksContext : DbContext
    {
        public BooksContext(DbContextOptions<BooksContext> options)
            : base(options) { }

        public DbSet<Book> Books { get; private set; }
        public DbSet<Chapter> Chapters { get; private set; }
        public DbSet<User> Users { get; private set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.ApplyConfiguration(new BookConfiguration());
            modelBuilder.ApplyConfiguration(new ChapterConfiguration());
            modelBuilder.ApplyConfiguration(new UserConfiguration());

            SeedData(modelBuilder);
        }

        private User[] _users = new[]
        {
            new User(1, "Christian Nagel"),
            new User(2, "Istvan Novak"),
            new User(3, "Charlotte Kughen")
        };
        private Book _book = new Book(1, "Professional C# 7 and .NET Core 2.0", "Wrox Press");
        private Chapter[] _chapters = new[]
        {
            new Chapter(1, 1, ".NET Applications and Tools"),
            new Chapter(2, 2, "Core C#"),
            new Chapter(3, 28, "Entity Framework Core")
        };

        protected void SeedData(ModelBuilder modelBuilder)
        {
            _book.AuthorId = 1;
            _book.ReviewerId = 2;
            _book.EditorId = 3;
            foreach (var c in _chapters)
            {
                c.BookId = 1;
            }

            modelBuilder.Entity<User>().HasData(_users);
            modelBuilder.Entity<Book>().HasData(_book);
            modelBuilder.Entity<Chapter>().HasData(_chapters);
        }
    }
}
复制代码

 

 

9. BooksService

复制代码
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace LazyLoading
{
    public class BooksService
    {
        private readonly BooksContext _booksContext;
        public BooksService(BooksContext booksContext)
        {
            _booksContext = booksContext ?? throw new ArgumentNullException(nameof(booksContext));
        }

        public void GetBooksWithLazyLoading()
        {
            var books = _booksContext.Books.Where(b => b.Publisher.StartsWith("Wrox"));

            foreach (var book in books)
            {
                Console.WriteLine(book.Title);
                Console.WriteLine(book.Publisher);
                foreach (var chapter in book.Chapters)
                {
                    Console.WriteLine($"{chapter.Number}. {chapter.Title}");
                }
                Console.WriteLine($"author: {book.Author?.Name}");
                Console.WriteLine($"reviewer: {book.Reviewer?.Name}");
                Console.WriteLine($"editor: {book.Editor?.Name}");
            }
        }

        public void GetBooksWithExplicitLoading()
        {
            var books = _booksContext.Books.Where(b => b.Publisher.StartsWith("Wrox"));

            foreach (var book in books)
            {
                Console.WriteLine(book.Title);
                EntityEntry<Book> entry = _booksContext.Entry(book);
                entry.Collection(b => b.Chapters).Load();

                foreach (var chapter in book.Chapters)
                {
                    Console.WriteLine($"{chapter.Number}. {chapter.Title}");
                }

                entry.Reference(b => b.Author).Load();
                Console.WriteLine($"author: {book.Author?.Name}");

                entry.Reference(b => b.Reviewer).Load();
                Console.WriteLine($"reviewer: {book.Reviewer?.Name}");

                entry.Reference(b => b.Editor).Load();
                Console.WriteLine($"editor: {book.Editor?.Name}");
            }
        }

        public void GetBooksWithEagerLoading()
        {
            var books = _booksContext.Books
                .Where(b => b.Publisher.StartsWith("Wrox"))
                .Include(b => b.Chapters)
                .Include(b => b.Author)
                .Include(b => b.Reviewer)
                .Include(b => b.Editor);

            foreach (var book in books)
            {
                Console.WriteLine(book.Title);
                foreach (var chapter in book.Chapters)
                {
                    Console.WriteLine($"{chapter.Number}. {chapter.Title}");
                }
                Console.WriteLine($"author: {book.Author?.Name}");
                Console.WriteLine($"reviewer: {book.Reviewer?.Name}");
                Console.WriteLine($"editor: {book.Editor?.Name}");
            }
        }

        public async Task DeleteDatabaseAsync()
        {
            Console.Write("Delete the database? ");
            string input = Console.ReadLine();

            if (input.ToLower() == "y")
            {
                bool deleted = await _booksContext.Database.EnsureDeletedAsync();
                Console.WriteLine($"database deleted: {deleted}");
            }
        }

        public async Task CreateDatabaseAsync()
        {
            bool created = await _booksContext.Database.EnsureCreatedAsync();
            string info = created ? "created" : "already exists";
            Console.WriteLine($"database {info}");
        }
    }
}
复制代码

 

 

10. AppServices

复制代码
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.IO;

namespace LazyLoading
{
    public class AppServices
    {
        private const string BooksConnection = nameof(BooksConnection);

        static AppServices()
        {
            Configuration = GetConfiguration();
        }

        private AppServices()
        {
            Container = GetServiceProvider();
        }

        public static AppServices Instance { get; } = new AppServices();

        public IServiceProvider Container { get; }

        public static IConfiguration GetConfiguration() =>
            new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                .Build();

        public static IConfiguration Configuration { get; }

        private ServiceProvider GetServiceProvider() =>
            new ServiceCollection()
                .AddLogging(config =>
                {
                    config
                        .AddConsole()
                        .AddDebug()
                        .AddFilter(level => level > LogLevel.Debug);
                })
                .AddTransient<BooksService>()
                .AddDbContext<BooksContext>(options =>
                {
                    options
                        .UseLazyLoadingProxies()
                        .UseSqlServer(Configuration.GetConnectionString(BooksConnection));
                })
                .BuildServiceProvider();
    }
}
复制代码

 

11. appsettings.json

{
  "ConnectionStrings": {
    "BooksConnection": "server=(localdb)\\MSSQLLocalDb;database=BooksLazy;trusted_connection=true"
  }
}

 

代码下载:https://files.cnblogs.com/files/Music/EntityFrameworkCore-Sample-LazyLoading.rar 

 

谢谢浏览!

 

点击右上角即可分享
微信分享提示