我在我的应用程序中使用实体框架,我有这样的一对多模型:
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
按预期为空。
我对Ef核心没有多少经验,如果我错过了一些课程,或者只是告诉我。
谢谢。
答案 0 :(得分:2)
这完全是由entity tracking引起的。行score
会导致实体框架跟踪整个while ((fgets(str, NAME_LENGTH, fp) != NULL) {
if (n % 2 == 0) {
printf("%d ",n / 2 + 1);
printf("%s",str);
} else {
printf("%s", str);
}
}
,如果您愿意,可以将其视为一种缓存形式。因为EF已经缓存了#34;那些dbSetAnexo.ToList();
个对象,当您请求DbSet
的值时,它会将它们呈现给您。
您可以使用AsNoTracking()
扩展方法阻止这种情况发生,例如:
AnexoEmail
现在,你应该做的是使用email.Anexos
函数来强制EF load up the specified related children。例如:
dbSetAnexo.AsNoTracking().ToList();
答案 1 :(得分:0)
这与.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自动完成功能,因为所有这些都在运行时进行检查。