编写直通类型关联的更好方法

时间:2012-10-14 20:17:23

标签: c#

在SQL中

我有一个像这样的表:

PersonOrganisationRole

有列:

PersonId, OrganisationId RoleId

因此,它是人员,组织和角色之间的三向表。

所以我想创建一种方法来获得一个人所属的所有组织:

public class Person
{
  public IEnumerable<Organisation> Organisations
        {
            get 
            { 
                var organisations = new List<Organisation>();

                foreach (var personOrganisationRole in PersonOrganisationRoles.Where(personOrganisationRole => !organisations.Contains(personOrganisationRole.Organisation)))
                {
                    organisations.Add(personOrganisationRoles.Organisation);
                }

                return organisations;
            }
        }
}

所以我基本上通过遍历表中的所有项目来填充列表,如果我还没有添加它,则只添加组织。这很重要,因为表中可能有多行具有相同的PersonId和OrganisationId,因为一个人可以在组织中拥有多个角色。

我想虽然必须有更好的方法来编写这段代码。

有什么建议吗?

4 个答案:

答案 0 :(得分:2)

您可以使用LINQ的Distinct运算符执行此唯一收集,并使用ToList将结果收集到列表中:

return PersonOrganisationRoles
    .Distinct(x => x.Organisation)
    .ToList();

答案 1 :(得分:1)

public IEnumerable<Organisation> Organisations
{
    get 
    { 
        return PersonOrganisationRoles
            .Select(por => por.Organisation)
            .Distinct()
            .ToList();
    }
}

您需要检查该组织是否已实施

  • GetHashcodeEquals正确
  • 可选择实施IEquatable<Organisation>

Distinct使用这些来确定该项目是否已在集合中。 (Contains在原始样本中做了同样的事情,所以这可能就是你想要的那样)

答案 2 :(得分:0)

使它成为一种功能,而不是财产。

我们习惯于编写objectInstance.PropertyName,并且通常认为这是访问已经在内存中的某些数据的快速操作。在您的情况下,对Person.Organizations的任何调用都涉及一些处理,甚至可能是IO操作。

另一个可能更重要的一点是,当我这样做时:

var a = myPerson.Organizations;
var b = myPerson.Organizations;

我希望a指向同一个List&lt;&gt;内存中的实例为b。

在您的代码中并非如此。因此,请更改属性以运行或将结果缓存在私有属性中,以便只进行一次处理。像这样:

public class Person
{
  private IEnumerable<Organisation> organizations; 

  public IEnumerable<Organisation> Organisations
  {
    get 
    { 
       if (organizations != null) return organizations;

       organisations = new List<Organisation>();
       // fill list here 
       return organisations;
     }
  }
}

答案 3 :(得分:0)

Linq Select()和Distinct()方法的组合应该这样做。

 var organisations = PersonOrganisationRoles
              .Select<PersonOrganisationRoles,Organisation>(p => p.Organisation )
              .Distinct();