3

例子

看看下面的代码:

private void DeDuplicateOrganisations()
{
     var profileOrgs = _organisations.Where(o => o.ExistsInProfile).ToList();
     var kvkOrgs = _organisations.Where(o => !o.ExistsInProfile).ToList();

     profileOrgs.ForEach(o =>
         {
             var duplicate = kvkOrgs.FirstOrDefault(k => k.KvK == o.KvK || k.Title == o.Title);
             if (duplicate != null)
             {
                  o.CompanyInfoOrganisation = duplicate.CompanyInfoOrganisation;
                  o.ExistsInBoth = true;
                  kvkOrgs.Remove(duplicate);
              }
           });

      _organisations = profileOrgs.Concat(kvkOrgs).OrderBy(o => o.Title).ToList();
}

在此示例中,CompanyInfoOrganisation当组织被视为重复时,将复制属性(简单地获取;设置;属性)。这一切都按预期工作,重复数据被很好地删除了。

在此消息中也是如此:
_organisations.First(o => o.ExistsInBoth).CompanyInfoOrganisation != null;

问题

现在我将列表绑定到_organisations列表框

lbxCompanies.DataSource = null;
lbxCompanies.DataSource = _organisations;
lbxCompanies.DisplayMember = "Title";
lbxCompanies.SelectedIndex = -1;

稍后获取所选值:

 var org = lbxCompanies.SelectedValue as Organisation;
 gbxCompanyInfo.Visible = org != null;
 if (gbxCompanyInfo.Visible)
    if (org.CompanyInfoOrganisation != null)
          // NEVER GETS HERE (but gbxComanpyInfo is visible)

如果我尝试读取CompanyInfoOrganisation属性,当我知道属性已设置时,我总是会得到 null。

问题

这里发生了什么?为什么属性引用被破坏了?我怎样才能防止这种情况发生?

4

4 回答 4

4

您正在使用的引用仅具有即时范围,并且一旦查询结束,它就会退出范围并且您的引用消失。所以当你稍后绑定时,引用是完全正确的——null。

profileOrgs.ForEach(o =>
{
    // Right here -- var duplicate has scope ONLY within your query. 
    // As soon as the query is executed it leaves scope and the reference
    // pointer will be null
    var duplicate = kvkOrgs.FirstOrDefault(k => k.KvK == o.KvK || k.Title == o.Title);
    if (duplicate != null)
    {
        o.CompanyInfoOrganisation = duplicate.CompanyInfoOrganisation;
        o.ExistsInBoth = true;
        kvkOrgs.Remove(duplicate);
    }
});

因为您使用的是一个类,所以您需要对其执行深层MemberwiseClone以获得对象的新副本:

o.CompanyInfoOrganisation = (YourInfoType)duplicate.CompanyInfoOrganisation.MemberwiseClone();
于 2012-07-11T11:49:53.053 回答
0

加载数据时,将 CompanyInfoOrganisation 属性与根实体一起加载;这样它就会被加载到内存中。如果使用 LINQ to SQL,则通过 DataLoadOptions 加载,并将其传递给上下文。如果使用实体框架,则在 LINQ 查询中使用 Include 方法。

于 2012-07-11T12:00:12.467 回答
0

它可能与捕获 lambda 中的变量有关。尝试将 .ForEach 替换为常规的 foreach()。或者,可能一式两份的 CompanyInfoOrganisation 一开始就为空。

于 2012-07-11T13:12:35.113 回答
0

问题是我用来string.Join()显示值,而要加入的第一个值是 null(这真的很烦人),导致一个空字符串,让我认为该属性是 null。然而事实证明,该属性不为空,而是对所需对象具有完全有效的引用。更小心地使用调试器会节省我一个小时左右的时间......

对不起!

于 2012-07-11T13:38:38.207 回答