实体框架 - 延迟加载或其他异步/等待查询方法?



我有这些域模型

public class Topic
{
public int TopicId { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public int? TopicId { get; set; }
public virtual Topic Topic { get; set; }
}

例如,我想暗示方法TestAsync,在那里我想使用主题对象和相关帖子对象。

主题模型我可以使用异步方法和主题 ID 作为参数获得。

public async Task<bool> TestAsync(int topicId)
{
var topic = await topicService.GetByIdAsync(topicId);
// posts ...
}

我有两种方法,如何获得相关帖子。 但是,如果我使用延迟加载或只是另一个异步查询,有什么区别?

// Example: 1 (LazyLoading)
var posts = topic.Posts;
// OR Example: 2 (Async method)
var posts = await postService.GetAllByTopicIdAsync(topicId);

所以,我认为 example:1 将同步工作,而且我失去了 async/await 代码的所有优点。 但是示例:2让我想,这可能是我不知道延迟加载的所有魅力:( 谁能澄清我应该使用什么解决方案以及为什么?谢谢:(

延迟加载始终是同步的,这很不幸。例如,EF Core 具有异步优先的心态,但(尚(不支持延迟加载。

其他选项是按照 Peter 的建议执行连接(预先加载(,异步执行单个查询;或者执行显式的第二个异步查询。选择哪一个取决于模型的正常使用方式。

就个人而言,如果模型始终一起使用,我会选择进行预先加载,否则会执行多个异步查询。我自己不使用延迟加载,尽管没有什么可以阻止它工作。

public async Task<TProperty> GetReferenceAsync<TEntity, TProperty>(DBContext context, TEntity entity, Expression<Func<TEntity, TProperty>> property)
where TEntity : class, IIdentifiable where TProperty : class
{
var getProperty = property.Compile();
var value = getProperty(entity);
if (value != null) { return value; }
await context.Entry(entity).Reference(property).LoadAsync();
return getProperty(entity);
}

用法:var posts = await GetReferenceAsync(context, topic, e => e.Posts);

你不应该做任何事。我假设你的GetByIdAsync((是这样实现的。

public async Task<Topic> GetByIdAsync(int id)
{
return await context.Topics.FirstAsync(t=>t.Id == id);
}

您应该将其更改为

public async Task<Topic> GetByIdAsync(int id)
{
return await context.Topics.Include(t=>t.Posts).FirstAsync(t=>t.Id == id);
}

最新更新