实体框架LINQ投影到自定义类型会导致数据丢失

时间:2010-10-05 16:51:22

标签: c# linq entity-framework entity-framework-4

我在Contractors和SafetyCouncils之间有很多关系。它们由一个桥梁表ContractorsSafetyCouncils加入,其中包括ContractorId和SafetyCouncilId。这两列构成一个复合键。此关系在EF4中正确映射。承包商实体拥有财产:

public virtual ICollection<SafetyCouncil> SafetyCouncils
{
    get;
    set;
}

SafetyCouncil实体具有以下属性:

public virtual ICollection<Contractor> Contractors
{
    get;
    set;
}

当通过延迟加载从单个Contractor或SafetyCouncil实体访问这些属性时,它们完全按预期工作。但是在查询中访问此关系时:

from c in ContractorRepository.All()
where c.PQFs.Count() > 0
let psmAudits = c.PQFs.SelectMany(pqf => pqf.Audits)
let psmAudit = psmAudits.FirstOrDefault(audit => audit.CompletedDate == psmAudits.Max(a => a.CompletedDate))
let scsAudits = c.PQFs.SelectMany(pqf => pqf.SCSAudits)
let scsAudit = scsAudits.FirstOrDefault(audit => audit.CompletedDate == scsAudits.Max(a => a.CompletedDate))
select new MasterListItem()
{
    AdministratorNotes = c.AdminFlags.Where(f => f.IsActive && f.ForPQF).Select(f => f.Text),
    CanViewInfo = false,
    ContractorName = c.ContractorName,
    ContractorId = c.Id,
    ContractorTaxId = c.TaxId,
    SafetyCouncilIds = c.SafetyCouncils.Select(sc => sc.Id),
    PQFSubmitted = c.PQFs.Max(p => p.PQFInfo.SubmittedDate.Value),
    PSMAuditId = psmAudit.Id,
    PSMAuditComplete = psmAudit.CompletedDate,
    PSMAuditStatus = psmAudit.Status.Description,
    SCSAuditId = scsAudit.Id,
    SCSAuditComplete = scsAudit.CompletedDate
};

问题出现在:

SafetyCouncilIds = c.SafetyCouncils.Select(sc => sc.Id),

对于每个记录,SafetyCouncilIds集合有0个成员,当基于数据库中的数据时,每个记录应该至少有1个与之关联的SafetyCouncilId。

如果我运行相同的查询,但投影到匿名类型而不是MasterListItem类型,它可以正常工作。为什么我不能将此查询投影到我的自定义类型中?

更新 我的MasterListItem POCO包含以下属性:

public string SafetyCouncilIdsString
{
    get;
    set;
}

public IEnumerable<int> SafetyCouncilIds
{
    set
    {
        StringBuilder sb = new StringBuilder(",");

        foreach (var id in value)
        {
            sb.Append(id);
            sb.Append(",");
        }

        this.SafetyCouncilIdsString = sb.ToString();
    }
}

SafetyCouncilIds属性是导致问题的原因。我将其更改为自动属性并在其他地方构建了字符串,投影到POCO就像一个魅力。

3 个答案:

答案 0 :(得分:2)

public IEnumerable<int> SafetyCouncilIds
{
    set
    {
        StringBuilder sb = new StringBuilder(",");

        foreach (var id in value)
        {
            sb = sb.Append(id).Append(","); // <-- try this
            // *or sb = sb.AppendFormat("{0},", id);*
        }

        this.SafetyCouncilIdsString = sb.ToString();
    }

}

答案 1 :(得分:0)

我有两点建议:

  1. 尝试通过删除查询的任何其他部分来隔离问题。
  2. 比较生成的两个sql查询并找出差异。
  3. 不幸的是,如果无法访问您的代码或架构,我无法提供更好的答案。

答案 2 :(得分:0)

SafetyCouncilIds属性是导致问题的原因。我将其更改为自动属性并在其他地方构建了字符串,投影到POCO就像一个魅力。