我在我的应用程序中使用实体框架,我有一个一对多的模型,如下所示:
public class Email
{
public string Id { get; set; }
public string To { get; set; }
public string From { get; set; }
public string CC { get; set; }
public string Bcc { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public ICollection<AnexoEmail> Anexos{get;set;}
}
public class AnexoEmail
{
[Key]
public string Id { get; set; }
/// <summary>
/// Full path do ficheiro
/// </summary>
public string Nome { get; set; }
public DateTime DataEnvio { get; set; }
public bool Enviado { get; set; }
public string EmailId { get; set; }
public Email Email { get; set; }
}它代表了一个电子邮件-附件关系。问题是,我有一个UOW和存储库EmailRepository,一些我无法理解的事情发生了:在存储库上:
public class EmailRepository : IEmailRepository
{
internal DbContext _context;
internal DbSet<Email> dbSet;
internal DbSet<AnexoEmail> dbSetAnexo;
public EmailRepository(DbContext context)
{
_context = context;
dbSet = context.Set<Email>();
dbSetAnexo = context.Set<AnexoEmail>();
}
(...)
public IEnumerable<Email> GetAll()
{
dbSetAnexo.ToList(); //<- I can´t understand this part
var emails = dbSet.ToList();
return email;
}
}在本例中,我希望emails.Anexos是null,但是由于某种原因,如果添加这一行,emails.Anexos将得到正确的附件(Anexos),如果没有,emails.Anexos将如预期的那样为null。
我没有多少经验的Ef核心,如果我错过了一些课程或其他什么只是告诉我。
谢谢。
发布于 2018-05-08 17:55:05
这一切都是由实体跟踪引起的。行dbSetAnexo.ToList();导致实体框架跟踪整个DbSet,如果您愿意,可以将其视为缓存的一种形式。因为EF“缓存”了这些AnexoEmail对象,所以当您请求email.Anexos的值时,它会将它们呈现给您。
可以通过使用AsNoTracking()扩展方法来防止这种情况发生,例如:
dbSetAnexo.AsNoTracking().ToList();现在,您应该做的是使用Include函数,这将强制EF到加载指定的相关子节点。。例如:
var emails = dbSet
.Include(e => e.Anexos)
.ToList();发布于 2018-05-08 17:11:22
这与.ToList()的实际工作有关。它不改变集合的原始值,它只是创建一个新的List<>并返回它。您目前正在做的是将值抛出窗口,而不是对其做任何操作。有两种存储方法:
DbSet<AnexoEmail> dbSetAnexo; // Keep original DbSet<>
List<AnexoEmail> listAnexo; // Make new List<AnexoEmail>
listAnexo = dbSetAnexo.ToList();然后,您将使用listAnexo而不是dbSetAnexo。如果您不喜欢这个类型,并且希望只使用一个变量,则可以使用dynamic类型,这是在运行时可以从一种类型更改为另一种类型的唯一类型。
dynamic anexoEmails = new DbSet<AnexoEmail>(); // anexoEmails is currently a dBSet<>
anexoEmails = anexoEmails.ToList(); // anexoEmails is now a List<>后者的行为可能更像你预期的那样。请记住,使用dynamic类型,您将不会得到那么多的编译器检查,没有IDE自动完成,所有这一切都是检查在运行时。
https://stackoverflow.com/questions/50238859
复制相似问题