如何简化此LINQ代码

时间:2013-11-19 09:41:27

标签: c# linq entity-framework multi-select

基本上我在MVC中有一个多选列表框,当用户更改选择时,它会返回并且应该更新模型。下面的代码有效,但我只是想知道如何将它放在一个foreach循环中,还是有更好的方法来更新选择?注意:艺术家和艺术家类型之间存在多种关系。

foreach (var artistTtype in this._db.ArtistTypes.ToList().Where(artistTtype => artist.ArtistTypes.Contains(artistTtype)))
{
    artist.ArtistTypes.Remove(artistTtype);
}

foreach (var artistTtype in this._db.ArtistTypes.ToList().Where(artisttype => vm.SelectedIds.Contains(artisttype.ArtistTypeID)))
{
    artist.ArtistTypes.Add(artistTtype);
}

2 个答案:

答案 0 :(得分:2)

这用于添加(只需使用AddRange):

artist.ArtistTypes.AddRange(this._db.ArtistTypes
         .Where(artisttype => vm.SelectedIds.Contains(artisttype.ArtistTypeID)));

这用于删除(使用ForEach):

 this._db.ArtistTypes
         .Where(artistTtype => artist.ArtistTypes.Contains(artistTtype)).ToList()
              .ForEach(x=>artist.ArtistTypes.Remove(x));

编辑:

你可以随时设置

artist.ArtistTypes = this._db.ArtistTypes
         .Where(artisttype => vm.SelectedIds.Contains(artisttype.ArtistTypeID)).ToList();

这会将ArtistTypes设置为你想要的,你不需要删除然后添加。

答案 1 :(得分:0)

我看到两个“修复”:

1)您不需要关心列表中的内容,因为您要更新可以从头开始的选择列表,因此删除部分变为

artist.ArtistTypes.Clear();

2)现在你再次填写清单。由于您正在执行.Where()来获取数据,因此不需要ToList(),并且您可以利用Linq的惰性机制,因此您只能读取实际使用的数据。您还可以拆分行以提高可读性(这没关系:在执行foreach()之前,db不会被实际命中。

//note that the .ToList() is gone
var query = this._db.ArtistTypes.Where(artisttype => vm.SelectedIds.Contains(artisttype.ArtistTypeID);
foreach (var artistTtype in query))
{
    artist.ArtistTypes.Add(artistTtype);
}

2b)(UNTESTED,在我的脑海中)实现比较的另一种方法是通过自定义IEqualityComparer,切换到.Intersect()方法。这样更加可靠,因为如果您的模型在模型中发生变化,您只需要更改比较器。

// I'm making up "ArtistType", fix according to your actual code
class ArtistTypeEqualityComparer : IEqualityComparer<ArtistType>
{
    public bool Equals(ArtistType x, ArtistType y)
    {
        if (ArtistType.ReferenceEquals(x, null)) return false;
        if (ArtistType.ReferenceEquals(y, null)) return false;
        if (ArtistType.ReferenceEquals(x, y)) return true;

        return x.ArtistTypeId.Equals(y.ArtistTypeId);
    }
    public int GetHashCode(ArtistType obj)
    {
        return obj.ArtistTypeId.GetHashCode();
    }
}

// And then the "add" part simplifies

artist.ArtistTypes.AddRange(this._db.ArtistTypes.Intersect(vm.SelectedIds.Select(x => new ArtistType{ ArtistTypeId = x }));