【问题标题】:Cannot implicitly convert type 'System.Collection.Generic.IEnumerable<string>' to 'string' while Adding data to the ViewModel在将数据添加到 ViewModel 时,无法将类型“System.Collection.Generic.IEnumerable<string>”隐式转换为“string”
【发布时间】:2020-03-06 02:06:37
【问题描述】:

使用 LinQ 时,可以从外键表数据中检索数据。但是,当我尝试将“添加”到我的 ViewModel 中时,会显示此警告。警告彼此不同。比如,

Cannot implicitly convert type 'System.Collection.Generic.IEnumerable<string>' to 'string'

Cannot implicitly convert type 'System.Collection.Generic.IEnumerable<System.Collection.Generic.IEnumerable.IEnumerable<string>' to 'string'.

我尝试转换为 ToString() 但它毫无价值,没有显示错误,但数据已替换为系统消息。我也尝试过 LinQ 加入学生,但我无法以这种方式显示技能逗号分隔。

这是我的代码:

         public ActionResult GetStudentsInfo ()
        {
            var students = (from stud in db.Students
                            group stud by stud.StudentId into sg

                            select new
                            {
                                studentName=sg.Select(s=>s.StudentName).FirstOrDefault(),
                                coutryName=sg.Select(c=>c.Country.CountryName),
                                cityName=sg.Select(ct=>ct.Country.Cities.Select(x=>x.CityName)),
                                skillName=sg.Select(sk=>sk.StudentSkills.Select(s=>s.Skill.SkillName)),
                                resumeName=sg.Select(r=>r.Resumes.Select(m=>m.ResumeName)),
                                dob=sg.Select(d=>d.DateOfBirth)

                            }).ToList();

            List<StudentListVM> studentLists=new List<StudentListVM>();

            foreach (var item in students)
            {
                studentLists.Add(new StudentListVM
                {
                    studentName = item.studentName,
                    country = item.coutryName, //warnings here
                    city = item.cityName, //warnings here
                    skills = string.Join(",", item.skillName),
                    resume = item.resumeName, //warnings here
                    dateOfBirth = item.dob //warnings here
                });
            }
            return View(studentLists);

        }

          ```

StudentListVM class



 public class StudentListVM
    {
        public string studentName { get; set; }
        public string country { get; set; }
        public string city { get; set; }
        public string skills { get; set; }
        public string resume { get; set; }
        public DateTime dateOfBirth { get; set; }
    }

    ```

我以前试过这个


 var students = (from stud in db.Students
                            join con in db.Countries on stud.CountryId equals con.CountryId
                            join ct in db.Cities on stud.CityId equals ct.CityId
                            join rsm in db.Resumes on stud.ResumeID equals rsm.ResumeId
                            join stsk in db.StudentSkills on stud.StudentId equals stsk.StudentId
                            //group stud by stud.StudentId into sg

                            select new StudentListVM()
                            {

                                studentName = stud.StudentName,
                                countries = con.CountryName,
                                cities = ct.CityName,
                                skills=stsk.Skill.SkillName,
                                resumes = rsm.ResumeName,
                                dateOfBirth = stud.DateOfBirth,



                            }).ToList();
        ```


StudentSkill class:

     public partial class StudentSkill
{
    public int StudentSkillsId { get; set; }
    public int StudentId { get; set; }
    public int SkillId { get; set; }

    public virtual Student Student { get; set; }
    public virtual Skill Skill { get; set; }
}

    ```

这将返回除逗号分隔列表中的技能之外的所有内容。我只需要显示我的多项技能,这些技能被多次检查并添加到数据库中的一个单独的表名 StudentSkills 中。有什么好的解决办法吗?

【问题讨论】:

标签: c# linq model-view-controller


【解决方案1】:

由于您的Select() 调用,您正试图将一组字符串,特别是各种IEnumerable&lt;string&gt; 集合分配到一个字符串中。

例如,这一行显然选择了多个简历名称。

resumeName=sg.Select(r=&gt;r.Resumes.Select(m=&gt;m.ResumeName))

如果您不在乎并期望它们具有相同的值,则可以直接获取第一个:

resume = item.resumeName.FirstOrDefault()

或者以其他方式展平集合。

也就是说,当您抓取一个集合并尝试将其分配给单个项目时,设计存在一些问题。

【讨论】:

  • 不,我要动态的方式,像技能一样,简历也可以多份。实际上我可以用不同的方式分别做它们,但我不能用一个代码来做。如果有任何最好的方法来做到这一点会更好。
【解决方案2】:

尝试改变这一行:

skills = string.Join(",", item.skillName),

有了这个:

skills = string.Join(",", item.skillName.ToArray()),

【讨论】:

    【解决方案3】:

    您遇到的问题不在您的代码中。问题是你认为你是如何解决它的。想对了,解决方案就对了。 @Zer0 已经提到过,但您可能需要更多解释。我将尝试用你可能想要做的一些假设来解释——

    1:如果Student 可以有多个国家、城市、技能和简历,那么您拥有的StudentVM 课程肯定是错误的。根据定义它只支持一个城市、国家、技能等。修改它以支持多个 -

    public class StudentListVM
    {
        public string studentName { get; set; }
        public List<string> countries { get; set; }
        public List<string> cities { get; set; }
        public string skills { get; set; }
        public List<string> resume { get; set; }
        //does not make sense to have a list, a person has only one DOB
        public DateTime dateOfBirth { get; set; }
    }
    

    那么你的代码就可以工作了 -

    public ActionResult GetStudentsInfo ()
        {
            var students = (from stud in db.Students
                            group stud by stud.StudentId into sg
    
                            select new
                            {
                                studentName=sg.Select(s=>s.StudentName).FirstOrDefault(),
                                coutryName=sg.Select(c=>c.Country.CountryName),
                                cityName=sg.Select(ct=>ct.Country.Cities.Select(x=>x.CityName)),
                                skillName=sg.Select(sk=>sk.StudentSkills.Select(s=>s.Skill.SkillName)),
                                resumeName=sg.Select(r=>r.Resumes.Select(m=>m.ResumeName)),
                                dob=sg.Select(d=>d.DateOfBirth).FirstOrDefault()
    
                            }).ToList();
    
            List<StudentListVM> studentLists=new List<StudentListVM>();
    
            foreach (var item in students)
            {
                studentLists.Add(new StudentListVM
                {
                    studentName = item.studentName,
                    countries = item.coutryName.ToList(), //should work, as these are lists
                    cities = item.cityName.ToList(), //should work, as these are lists
                    skills = string.Join(",", item.skillName),
                    resume = item.resumeName.ToList(), //should work, as these are lists
                    dateOfBirth = item.dob //does not make sense to have a list, a person has only one DOB
                });
            }
            return View(studentLists);
    }
    

    2:一旦课程没问题,您就可以缩短代码。您不需要第二个块来创建类型化列表,您可以直接进行 -

    public ActionResult GetStudentsInfo ()
        {
            var students = (from stud in db.Students
                            group stud by stud.StudentId into sg
    
                            select new StudentListVM
                            {
                                studentName=sg.Select(s=>s.StudentName).FirstOrDefault(),
                                countries=sg.Select(c=>c.Country.CountryName).ToList(),
                                cities=sg.SelectMany(ct=>ct.Country.Cities.Select(x=>x.CityName)).ToList(),
                                skills=string.Join(",", sg.Select(sk=>sk.StudentSkills.Select(s=>s.Skill.SkillName))),
                                resume=sg.SelectMany(r=>r.Resumes.Select(m=>m.ResumeName)).ToList(),
                                //does not make sense to have a list, a person has only one DOB
                                dob=sg.Select(d=>d.DateOfBirth).FirstOrDefault()
    
                            }).ToList();
       return View(students);
    }
    

    3:如果以上没有意义,那么这个想法是不对的。想想你想要达到的目标并更新问题。也许那时人们将能够提供帮助。

    你说过——

    实际上我可以用不同的方式分别完成它们,但我不能在一个代码中完成

    那么这些方法是什么?提及它们可能会让您了解您想要实现的目标。问题的详细信息不足以为您提供解决方案。它没有说明您要做什么。

    【讨论】:

    • 我想要一个包含上述所有列的列表,我可以通过 LINQ Join 来完成它并且它可以工作,技能列中唯一的问题不能以这种方式工作并且不能被添加我知道一个单独的代码,它是对它们进行分组并通过 foreach 语句添加。所以我正在以一种未知的方式尝试自己的方式。我会按照你的方式尝试,然后让你知道。
    • 对不起!城市和简历仍然从您的解决方案中收到相同的警告。那有什么解决办法呢?
    • 可能是因为这是双重选择sg.Select(ct=&gt;ct.Country.Cities.Select(x=&gt;x.CityName))。试试SelectMany 我已经更新了答案。这将使列表变平,我建议先阅读它 - docs.microsoft.com/en-us/dotnet/api/…
    • 顺便说一句,我没有给出解决方案,整个结构需要修复。因此,我建议重新考虑您的策略并重新实施。
    猜你喜欢
    • 1970-01-01
    • 2013-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-03
    • 1970-01-01
    相关资源
    最近更新 更多