如何遍历数组并将每个值添加到模型变量中? MVC Razor

时间:2015-08-03 20:31:10

标签: asp.net-mvc asp.net-mvc-4 razor model-view-controller foreach

我正在尝试在我的模型中创建一个变量,该变量检索所有可用的技能,以便稍后在DDL中显示它们。我有一个包含所有技能的变量和一个显示员工已经评定的所有技能的变量。我想检查所有针对额定技能的技能,以便只将未评级的技能添加到模型中的新变量中。我能想到的唯一方法是使用foreach循环来检查AllSkills变量中的值。

模型:

public IEnumerable<long> AvailableSkills { get; set; }
public IEnumerable<long> AllSkills { get; set; }
public IEnumerable <long> EmployeeRatings { get; set; }          
public IEnumerable<Rating> Ratings { get; set; }
public IEnumerable<Skill> Skills { get; set; }
public long SkillId { get; set; }

控制器:

model.AllSkills = db.Skills.OrderBy(s => s.SkillName).Select(s => s.SkillId);
model.EmployeeRatings = db.Ratings.Where(r => r.EmployeeId == User.Identity.Name.Remove(0, 8)).OrderBy(s => s.SkillId).Distinct();

foreach (var skill in model.EmployeeRatings)
        {
            model.AvailableSkills = model.AllSkills.Where(s => s != skill);
        }

我想在foreach循环中执行类似以下代码的操作:

model.AvailableSkills += model.AllSkills.Where(s=> s != skill); but this is not allowed.

问题在于,对于上面的每个循环,这都是将model.AvailableSkills分配给每个技能,但是foreach循环中的最后一个技能(应该如此)。我如何做到这一点,以便从模型中排除每一个重复技能.AvailableSkills?

4 个答案:

答案 0 :(得分:1)

如果您使用查询与方法链接语法相反的语法,则使用LINQ可以使IMO更具可读性。

model.AllSkills = 
   from skill in db.Skills
   orderby skill.SkillName
   select skill.SkillId;

model.EmployeeRatings = 
     from rating in db.Ratings
     let employeeId = User.Identity.Name.Remove(0, 8)
     where rating.EmployeeId == employeeId
     orderby rating.SkillId
     select rating.SkillId

您可以使用Except() extension method从集合中删除项目。

// exclude the 'owned' skils
model.AvailableSkills = model.AllSkills.Except(model.EmployeeRatings);

你可能希望区分结果:

model.AvailableSkills = model.AvailableSkills.Distinct(); 

最后但并非最不重要: 因为您选择SkillId我不确定您为什么要订购结果。这没有任何意义,特别是因为您在两个列表中按不同的属性进行排序。此外,您可能希望选择要向用户显示的更多详细信息,但要了解这一点,我们需要有关您的模型的更多详细信息。

答案 1 :(得分:0)

假设EmployeeRatings包含额定技能,并且您希望AvailableSkills只具有不在EmployeeRatings但在AllSkills中的技能,我认为这是您喜欢的:

model.AvailableSkills = model.AllSkills
     .Where(s => !model.EmployeeRatings.Contains(s));

答案 2 :(得分:0)

考虑两个这样的类:

public class Skill
{
    public int Id { get; set; }
}

public class Employee
{
    public int[] RatedSkills { get; set; }
}

var skills = new List<Skill>
        {
            new Skill{ Id = 1}, new Skill{Id = 2}, new Skill{ Id = 3}, new Skill { Id = 4}
        };

        var emp = new Employee
        {
            RatedSkills = new int[] { 1,2 }
        };

        var availableSkills = skills.Select(s => s.Id).Except(emp.RatedSkills);

        Console.Read();

评级具有Id属性,员工拥有int[]来保留他/她选择的评级。从那里很容易过滤

答案 3 :(得分:0)

按照当前的方法,您可以将AddRange与列表一起使用。类似的东西:

List<long> availableSkills = new List<long>();

foreach (var skill in model.EmployeeRatings)
{
    availableSkills.AddRange(model.AllSkills.Where(s => s != skill));
}

model.AvailableSkills = availableSkills;

或者您可以通过更紧凑的方法实现这一目标,我相信Except会删除欺骗:

model.AvailableSkills = model.AllSkills.Except(model.EmployeeRatings);