DbSet.ToList()种子其他dbset

时间:2018-05-08 17:03:05

标签: c# entity-framework asp.net-core

我在我的应用程序中使用实体框架,我有这样的一对多模型:

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.Anexosnull,但由于某种原因,如果我添加该行,emails.Anexos会获得正确的附件(anexos),如果我不要emails.Anexos按预期为空。

我对Ef核心没有多少经验,如果我错过了一些课程,或者只是告诉我。

谢谢。

2 个答案:

答案 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自动完成功能,因为所有这些都在运行时进行检查。