直接贴代码了:

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()
.IsRequired();
builder.Property(b => b.Publisher)
.HasMaxLength()
.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(, "Christian Nagel"),
new User(, "Istvan Novak"),
new User(, "Charlotte Kughen")
};
private Book _book = new Book(, "Professional C# 7 and .NET Core 2.0", "Wrox Press");
private Chapter[] _chapters = new[]
{
new Chapter(, , ".NET Applications and Tools"),
new Chapter(, , "Core C#"),
new Chapter(, , "Entity Framework Core")
}; protected void SeedData(ModelBuilder modelBuilder)
{
_book.AuthorId = ;
_book.ReviewerId = ;
_book.EditorId = ;
foreach (var c in _chapters)
{
c.BookId = ;
} 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

谢谢浏览!

EntityFrameworkCore 学习笔记之示例一的更多相关文章

  1. 【原创】SpringBoot & SpringCloud 快速入门学习笔记(完整示例)

    [原创]SpringBoot & SpringCloud 快速入门学习笔记(完整示例) 1月前在系统的学习SpringBoot和SpringCloud,同时整理了快速入门示例,方便能针对每个知 ...

  2. 【工作笔记】BAT批处理学习笔记与示例

    BAT批处理学习笔记 一.批注里定义:批处理文件是将一系列命令按一定的顺序集合为一个可执行的文本文件,其扩展名为BAT或者CMD,这些命令统称批处理命令. 二.常见的批处理指令: 命令清单: 1.RE ...

  3. Spring Cloud 微服务架构学习笔记与示例

    本文示例基于Spring Boot 1.5.x实现,如对Spring Boot不熟悉,可以先学习我的这一篇:<Spring Boot 1.5.x 基础学习示例>.关于微服务基本概念不了解的 ...

  4. Dubbo -- 系统学习 笔记 -- 示例 -- 泛化引用

    Dubbo -- 系统学习 笔记 -- 目录 示例 想完整的运行起来,请参见:快速启动,这里只列出各种场景的配置方式 泛化引用 泛接口调用方式主要用于客户端没有API接口及模型类元的情况,参数及返回值 ...

  5. Dubbo -- 系统学习 笔记 -- 示例 -- 结果缓存

    Dubbo -- 系统学习 笔记 -- 目录 示例 想完整的运行起来,请参见:快速启动,这里只列出各种场景的配置方式 结果缓存 结果缓存,用于加速热门数据的访问速度,Dubbo提供声明式缓存,以减少用 ...

  6. Dubbo -- 系统学习 笔记 -- 示例 -- 分组聚合

    Dubbo -- 系统学习 笔记 -- 目录 示例 想完整的运行起来,请参见:快速启动,这里只列出各种场景的配置方式 分组聚合 按组合并返回结果,比如菜单服务,接口一样,但有多种实现,用group区分 ...

  7. Dubbo -- 系统学习 笔记 -- 示例 -- 多版本

    Dubbo -- 系统学习 笔记 -- 目录 示例 想完整的运行起来,请参见:快速启动,这里只列出各种场景的配置方式 多版本 当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间 ...

  8. Dubbo -- 系统学习 笔记 -- 示例 -- 服务分组

    Dubbo -- 系统学习 笔记 -- 目录 示例 想完整的运行起来,请参见:快速启动,这里只列出各种场景的配置方式 服务分组 当一个接口有多种实现时,可以用group区分. <dubbo:se ...

  9. Dubbo -- 系统学习 笔记 -- 示例 -- 多注册中心

    Dubbo -- 系统学习 笔记 -- 目录 示例 想完整的运行起来,请参见:快速启动,这里只列出各种场景的配置方式 多注册中心 可以自行扩展注册中心,参见:注册中心扩展 (1) 多注册中心注册 比如 ...

随机推荐

  1. php捕获Fatal error错误与异常处理

    php中的错误和异常是两个不同的概念. 错误:是因为脚本的问题,比如少写了分号,调用未定义的函数,除0,等一些编译语法错误. 异常:是因为业务逻辑和流程,不符合预期情况,比如验证请求参数,不通过就用 ...

  2. 用go-module作为包管理器搭建go的web服务器

    本篇博客主要介绍了如何从零开始,使用Go Module作为依赖管理,基于Gin来一步一步搭建Go的Web服务器.并使用Endless来使服务器平滑重启,使用Swagger来自动生成Api文档. 源码在 ...

  3. Entity Framework 基础操作(1)

    EF是微软推出的官方ORM框架,默认防注入可以配合LINQ一起使用,更方便开发人员. 首先通过SQLSERVER现在有的数据库类生产EF 右键->添加->新建项,选择AOD.NET实体数据 ...

  4. python基础(28):isinstance、issubclass、type、反射

    1. isinstance和issubclass 1.1 isinstance isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo(object): pa ...

  5. PHP-Curl模拟HTTPS请求

     使用PHP-Curl方式模拟HTTPS请求,测试接口传参和返回值状态   上代码!! <?php /** * 模拟post进行url请求 * @param string $url * @par ...

  6. HTML语法规范

    HTML语法规范 语法规范概述 HTML标签是由尖括号包围的关键词,例如<html> HTML标签通常是成对出现的,例如<html> 和</html> ,我们成为双 ...

  7. Web安全攻防笔记-SQL注入

    information_schema(MySQL5.0版本之后,MySQL数据库默认存放一个information_schema数据库) information_schema的三个表: SCHEMAT ...

  8. 【转载】Android开发中巧用Activity和Fragment

    1.Activity的生命周期 1)多个Activity组成Activity栈,当前活动位于栈顶.我们先来看看各种Activity基类的类图: 当Activity类定义出来之后,这个Activity何 ...

  9. iOS10跳转至设置页面

    在iOS10之前,跳转到系统设置界面的某个指定界面的方式如下: //打开定位服务界面 NSURL*url=[NSURL URLWithString:@"prefs:root=Privacy& ...

  10. Android Toolbar中的title居中问题

    版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/167 Android Toolbar中的title居中问题 ...