SslSugar导航查询与EF Core导航查询

SqlSugar高级篇    SqlSugar官网

SqlSugar:

当我们在SQLSugar中定义了两个实体类之间的关联关系时,可以使用导航属性进行关联查询。导航属性是表示一个实体对象与其他实体对象之间关联的属性。通过导航属性,我们可以方便地在查询中访问和检索相关联的实体数据。

在SQLSugar中,导航属性需要满足以下条件:

  • 导航属性必须为可访问的公共属性(Public)。
  • 导航属性的类型必须是另一个实体类或实体类集合。

下面我们以作者(Author)和书籍(Book)为例进行说明。假设我们有以下的实体类定义:

public class Author
{
    [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
    public int AuthorId { get; set; }
    public string Name { get; set; }

    [SugarColumn(IsIgnore = true)]
    public List<Book> Books { get; set; }
}

public class Book
{
    [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
    public int BookId { get; set; }
    public string Title { get; set; }
    public int AuthorId { get; set; }

    [SugarColumn(IsIgnore = true)]
    public Author Author { get; set; }
}

在示例中,作者(Author)类包含了一个导航属性Books,它用于表示一个作者可以拥有多本书。而书籍(Book)类包含了一个导航属性Author,它用于表示一本书只能有一个作者。

接下来,我们可以使用导航属性进行查询的示例代码:

using SqlSugar;

// 创建SqlSugarClient对象
var db = new SqlSugarClient(new ConnectionConfig()
{
    ConnectionString = "YourConnectionString",
    DbType = DbType.SqlServer,
    IsAutoCloseConnection = true
});

// 查询特定作者的所有书籍
var authorWithBooks = db.Queryable<Author>()
    .Where(author => author.AuthorId == 1)
    .Mapper(c => c.Books, c =>
    {
        c.Books = db.Queryable<Book>().Where(book => book.AuthorId == c.AuthorId).ToList();
    })
    .First();

// 查询特定书籍的作者信息
var bookWithAuthor = db.Queryable<Book>()
    .Where(book => book.BookId == 1)
    .Mapper(c => c.Author, c =>
    {
        c.Author = db.Queryable<Author>().Where(author => author.AuthorId == c.AuthorId).First();
    })
    .First();

在以上示例中,我们使用了Queryable方法来进行查询操作,并通过Mapper方法来加载关联的实体数据。

对于查询特定作者的所有书籍的例子,我们首先使用Queryable<Author>来查询作者表,并指定了一个条件author => author.AuthorId == 1。然后,使用Mapper方法来映射导航属性Books的查询结果。在这个例子中,我们使用db.Queryable<Book>().Where(book => book.AuthorId == c.AuthorId).ToList()来加载作者的所有书籍,并将结果赋值给导航属性c.Books

对于查询特定书籍的作者信息的例子,我们首先使用Queryable<Book>来查询书籍表,并指定了一个条件book => book.BookId == 1。然后,使用Mapper方法来映射导航属性Author的查询结果。在这个例子中,我们使用db.Queryable<Author>().Where(author => author.AuthorId == c.AuthorId).First()来加载书籍的作者信息,并将结果赋值给导航属性c.Author

通过这种方式,我们可以方便地使用导航属性进行关联查询,从而获取相关实体之间的数据。导航查询能够简化代码逻辑,提高开发效率,并且使代码更加易读和可维护。

 

EF Core:

 

在Entity Framework (EF) Core中,导航查询是通过使用导航属性来实现关联查询的过程。EF Core提供了丰富的API和语法来支持导航属性的使用,使得进行关联查询变得非常便捷。

下面我将介绍一下在EF Core中如何进行导航查询的基本原理和示例代码。

基本原理

在EF Core中,我们可以定义实体类之间的关联关系,并在实体类中使用导航属性来表示这种关系。通过导航属性,我们可以轻松地在查询中访问和检索相关联的实体数据。

当我们执行导航查询时,EF Core会自动根据定义的关联关系和导航属性来构建相应的 SQL 查询语句,从而获取相关联的实体数据。

示例代码

假设我们有以下的实体类定义:作者(Author)和书籍(Book)。

public class Author
{
    public int AuthorId { get; set; }
    public string Name { get; set; }
    public List<Book> Books { get; set; }
}

public class Book
{
    public int BookId { get; set; }
    public string Title { get; set; }
    public int AuthorId { get; set; }
    public Author Author { get; set; }
}

接下来,我们可以使用导航属性进行查询的示例代码:

using Microsoft.EntityFrameworkCore;

// 创建DbContext对象
var dbContext = new YourDbContext();

// 查询特定作者的所有书籍
var authorWithBooks = dbContext.Authors
    .Include(author => author.Books)
    .FirstOrDefault(author => author.AuthorId == 1);

// 查询特定书籍的作者信息
var bookWithAuthor = dbContext.Books
    .Include(book => book.Author)
    .FirstOrDefault(book => book.BookId == 1);

在以上示例中,我们使用了EF Core中的Include方法来指定要包含的导航属性,以便在查询中加载相关联的实体数据。通过指定导航属性,我们可以轻松地实现关联查询的操作。

需要注意的是,在EF Core中,导航属性的加载策略对性能影响很大。通过Include方法可以指定要预先加载的导航属性,以避免产生额外的查询。此外,EF Core还提供了延迟加载等方式来动态加载导航属性的数据,以进一步优化查询性能。

总之,EF Core中的导航查询通过使用导航属性和相应的加载策略,使得关联查询变得非常便捷和灵活。开发人员可以根据具体的业务需求和性能考量,选择合适的加载策略来优化导航查询的性能。

Include:

Include 是 Entity Framework Core (EF Core) 中的一个方法,用于指定在查询中预先加载相关的导航属性。

在 EF Core 中,导航属性表示实体类之间的关联关系。通过导航属性,我们可以轻松地在查询中访问和检索相关联的实体数据。但是,默认情况下,在查询实体时,EF Core 只会加载主实体,而不会自动加载相关的导航属性。这种情况下,如果我们想要获取相关联的实体数据,就需要使用 Include 方法来显式地指定要预加载的导航属性。

Include 方法接受一个 lambda 表达式作为参数,用于指定要包含的导航属性。这样,当执行查询时,EF Core 将会自动构造相应的 SQL 查询语句,同时加载指定的导航属性的数据。

以下是一个使用 Include 方法的示例代码:

using Microsoft.EntityFrameworkCore;

// 创建 DbContext 对象
var dbContext = new YourDbContext();

// 查询特定作者的所有书籍,并同时加载书籍的详细信息
var authorWithBooks = dbContext.Authors
    .Include(author => author.Books) // 指定要包含的导航属性
    .FirstOrDefault(author => author.AuthorId == 1);

在上面的示例中,我们通过 Include 方法指定了要加载的导航属性 Books,它表示 Author 实体与 Book 实体之间的关联关系。这样,当执行查询时,EF Core 将会加载特定作者的所有书籍,并将其赋值给 authorWithBooks 变量。

需要注意的是,使用 Include 方法来预先加载导航属性的数据可以避免产生额外的数据库查询,从而提高查询的性能。但是,当导航属性的层次较深或者有多个导航属性时,我们需要谨慎使用 Include 方法,以避免加载过多的数据和影响性能。在这种情况下,我们可能需要考虑使用其他加载策略,如延迟加载或显式加载,来实现更精确的数据加载。

注解:

当我们使用EF Core进行关联查询时,实际上是在查询主实体的同时,通过导航属性访问和获取相关联的实体数据。这种方式可以避免多次查询数据库,提高查询效率和性能。

在EF Core中,我们可以使用以下几种方式来进行导航查询:

  1. 延迟加载:当我们首次访问导航属性时,EF Core会自动异步地加载相关联的实体数据。这种方式不需要显式指定导航属性的加载策略,但可能会产生额外的数据库查询,影响性能。

    示例代码:

    // 延迟加载书籍
    var author = dbContext.Authors.FirstOrDefault(a => a.AuthorId == 1);
    var books = author.Books; // 第一次访问导航属性会自动异步加载相关联的书籍数据
  2. 预先加载:通过使用Include方法指定要预先加载的导航属性,可以在查询主实体时同时加载所有相关联的实体数据,从而避免产生额外的数据库查询。这种方式需要显式指定导航属性的加载策略。

    示例代码:

    // 预先加载书籍
    var authorWithBooks = dbContext.Authors.Include(author => author.Books).FirstOrDefault(a => a.AuthorId == 1);
    var books = authorWithBooks.Books; // 直接访问导航属性,无需再次查询数据库
    JAVASCRIPT 复制 全屏
  3. 显式加载:通过使用Load方法手动加载导航属性的数据,可以在查询主实体后,根据需要动态加载相关联的实体数据。

    示例代码:

    // 显式加载书籍
    var author = dbContext.Authors.FirstOrDefault(a => a.AuthorId == 1);
    dbContext.Entry(author).Collection(a => a.Books).Load(); // 手动加载导航属性的数据
    var books = author.Books; // 直接访问导航属性,无需再次查询数据库

需要注意的是,在进行导航查询时,EF Core会自动构建相应的SQL查询语句,以获取相关联的实体数据。因此,我们需要根据具体业务需求和性能考量,选择合适的加载策略来优化导航查询的性能。同时,也需要避免产生额外的数据库查询,以避免对数据库服务器造成过大的负载。

posted on 2024-05-28 16:22  大西瓜3721  阅读(141)  评论(0编辑  收藏  举报

导航