C# 在强类型视图中显示来自多个表的数据

C# 在强类型视图中显示来自多个表的数据,c#,asp.net-mvc,linq,asp.net-mvc-4,razor,C#,Asp.net Mvc,Linq,Asp.net Mvc 4,Razor,我有一个强类型视图,它显示数据库表“Student_a”中的学生 视图: 我有另一个表“Student_B”,它也存储学生,我也想在我的视图中显示这些学生。比如: public ActionResult ShowAllStudents() { var StudentA = stud.Student_A.Where(a => a.StudentId != 0); var StudentB = stud.Student_B.Where(a =&g

我有一个强类型视图,它显示数据库表“Student_a”中的学生

视图:

我有另一个表“Student_B”,它也存储学生,我也想在我的视图中显示这些学生。比如:

    public ActionResult ShowAllStudents()
    {
        var StudentA = stud.Student_A.Where(a => a.StudentId != 0);
        var StudentB = stud.Student_B.Where(a => a.StudentId != 0);
        ViewData.Model = StudentA + StudentB;

        return View();
    }
是否可以在一个控制器操作中在强类型视图中显示来自两个不同表的数据?或者我必须创建一个数据库视图来显示“Student_a”和“Student_B”表中的学生,然后在视图中显示他们


非常感谢您的帮助

您需要以“不可知”的方式存储结果。比如说

public class StudentInfo
{
public string Type { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
...
}


var students = stud.Student_A.Where(...).Select(a => new StudentInfo { Type = "Student_A", FirstName = a.FirstName, LastName = a.LastName });

students.concat( stud.Student_B.Where(...).Select(b => new StudentInfo { Type = "Student_B", FirstName = b.FirstName, LastName = b.LastName });

ViewData.Model = students;

return View();
通过这样做,您就有了一个公共的学生信息类来存储可以用作强类型模型的公共属性

或者,如果要单独列出它们,可以创建复合ViewModel

public class StudentsVM
{
public IEnumerable<Student_A> Student_A { get; set; }
public IEnumerable<Student_B> Student_B { get; set; }
}

var vm = new StudentsVM;
vm.Student_A = stud.Student_A.Where(...);
vm.Student_B = stud.STudent_B.Where(...);

ViewData.Model = vm;
公共班级学生SVM
{
公共IEnumerable Student_A{get;set;}
公共IEnumerable Student_B{get;set;}
}
var vm=新学生SVM;
vm.Student_A=stud.Student_A.Where(…);
vm.Student_B=stud.Student_B.Where(…);
ViewData.Model=vm;

您可以使用这两种方法创建视图模型

public class StudentsViewModel
{
  public List<Student.Models.Student_A> StudentsA {get;set}
  public List<Student.Models.Student_B> StudentsA {get;set}
}

我必须对Treeview而不是表执行类似的操作,并且需要组合两个不同的集合,以便从单个集合生成Treeview。在我的情况下,我能够结合他们使用这个

var allStudents = StudentA.Union((IEnumerable<Object>)StudentB);
var allStudents=StudentA.Union((IEnumerable)StudentB);
然后在代码中,当您迭代集合中的每个对象时,您可以测试对象的数据类型,并以您想要的方式显示它,以防您想要使用不同的代码呈现不同类型的学生。我需要这样做,因为在我的例子中,有子项的节点与没有子项的节点是完全不同的类型

请注意,通过使用对象作为根集合类型而不是某种共享继承(例如接口),您将无法对组合集合进行排序或筛选

如果需要混合这两个集合,而不是将一个集合追加到另一个集合的末尾,则必须使用某种共享继承

更新

示例代码显示了这一点。我在中进行了测试,但我确信它在VisualStudio中也能正常工作

public class Student_A
{
    public int Id{get;set;}
    public string FirstName{get;set;}
    public string LastName{get;set;}
}

public class Student_B
{
    public int Id{get;set;}
    public string FirstName{get;set;}
    public string MiddleName{get;set;}
    public string LastName{get;set;}
}

void Main()
{
    List<Student_A> StudentAs = new List<Student_A>();
    StudentAs.Add(new Student_A(){Id = 1, FirstName = "Jack", LastName = "Smith"});
    StudentAs.Add(new Student_A(){Id = 3, FirstName = "Sarah", LastName = "Jane"});
    StudentAs.Add(new Student_A(){Id = 7, FirstName = "Zack", LastName = "Hall"});

    List<Student_B> StudentBs = new List<Student_B>();
    StudentBs.Add(new Student_B(){Id = 2, FirstName = "Jane", MiddleName = "T.", LastName = "Kelly"});
    StudentBs.Add(new Student_B(){Id = 9, FirstName = "Rose", MiddleName = "Marie", LastName = "Tyler"});
    StudentBs.Add(new Student_B(){Id = 4, FirstName = "Bobby", MiddleName = "Stephen", LastName = "Singer"});

    var result = StudentAs.Union((IEnumerable<Object>)StudentBs);

    result.Dump();
}
公共班级学生
{
公共int Id{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
}
公立班学生
{
公共int Id{get;set;}
公共字符串名{get;set;}
公共字符串MiddleName{get;set;}
公共字符串LastName{get;set;}
}
void Main()
{
List StudentAs=新列表();
Add(newstudent_A(){Id=1,FirstName=“Jack”,LastName=“Smith”});
Add(newstudent_A(){Id=3,FirstName=“Sarah”,LastName=“Jane”});
Add(newstudent_A(){Id=7,FirstName=“Zack”,LastName=“Hall”});
List StudentBs=新列表();
Add(new Student_B(){Id=2,FirstName=“Jane”,MiddleName=“T.”,LastName=“Kelly”});
Add(new Student_B(){Id=9,FirstName=“Rose”,MiddleName=“Marie”,LastName=“Tyler”});
Add(newstudent_B(){Id=4,FirstName=“Bobby”,MiddleName=“Stephen”,LastName=“Singer”});
var结果=学生联盟((IEnumerable)学生B);
result.Dump();
}

这样就不能有强类型视图,对吗?在这种情况下,我的视图将继承什么?对于在顶部定义页面视图模型的实际行,您是对的
@model IEnumerable
。但是,当您迭代对象集合时,如果您想要获得正确的intellisense,您可以将对象强制转换或寻址为其实际类型。或者,您可以传递一个强类型视图模型,其中集合作为单独的属性,并根据需要在视图中组合它们,以便在单个表中显示它们。如果我还记得的话,这也是我在我的案例中最后所做的。当我尝试您建议的方法时,出现了一个错误:“System.collections.Generic.List不包含“Union”的定义和最佳扩展方法重载”System.Linq.Queryable.Union(System.Linq.IQueryable,System.collections.Generic.IEnumerable)'有一些无效的参数。这是系统中的一个扩展方法。Linq,您可能必须确保名称空间从您使用的页面解析。我刚刚检查了它,它似乎对我很好,我的确切代码行的唯一区别是一些排序。。。这是我的项目中的一句话,也许它能帮助你找出为什么你的项目会出现这样的错误
(typeItem.Structures.OrderBy(x=>x.Priority).然后by(x=>x.DisplayName)).Union((IEnumerable)typeItem.Types.OrderBy(x=>x.DisplayName))
也可以将第一个集合强制转换为IEnumerable?我的视图将继承什么?“对象”?在第一种方法中,我如何在视图中显示结果?您的模型是
IEnumerable
此列表包含多个学生,我是否有太多的模型项循环以显示所有?如果我没有“IEnumerable”,它会给出和错误。但是,当我添加“IEnumerable”时,会出现以下错误:编译器错误消息:CS0246:找不到类型或命名空间名称“StudentsViewModel”(是否缺少using指令或程序集引用?)
StudentsViewModel
在哪个命名空间中
IEnumerable
或者,您可以在web.config中添加名称空间。有关当前自动导入的命名空间的列表,请参见web.config。但对于测试,我首先使用完整的名称空间。Inherits=“System.Web.Mvc.ViewPage此列表包含多个学生,因此我必须循环遍历模型项。如果没有“IEnumerable”,则会出现错误。但是,当我添加“IEnumerable”时“我收到以下错误:编译器错误消息:CS0246:找不到类型或命名空间名称‘StudentsViewModel’(是否缺少using指令或程序集引用?)
var viewModel = new StudentsViewModel();
viewModel.StudentsA = stud.Student_A.Where(a => a.StudentId != 0);
viewModel.StudentsB = stud.Student_B.Where(a => a.StudentId != 0);
return View(viewModel);
var allStudents = StudentA.Union((IEnumerable<Object>)StudentB);
public class Student_A
{
    public int Id{get;set;}
    public string FirstName{get;set;}
    public string LastName{get;set;}
}

public class Student_B
{
    public int Id{get;set;}
    public string FirstName{get;set;}
    public string MiddleName{get;set;}
    public string LastName{get;set;}
}

void Main()
{
    List<Student_A> StudentAs = new List<Student_A>();
    StudentAs.Add(new Student_A(){Id = 1, FirstName = "Jack", LastName = "Smith"});
    StudentAs.Add(new Student_A(){Id = 3, FirstName = "Sarah", LastName = "Jane"});
    StudentAs.Add(new Student_A(){Id = 7, FirstName = "Zack", LastName = "Hall"});

    List<Student_B> StudentBs = new List<Student_B>();
    StudentBs.Add(new Student_B(){Id = 2, FirstName = "Jane", MiddleName = "T.", LastName = "Kelly"});
    StudentBs.Add(new Student_B(){Id = 9, FirstName = "Rose", MiddleName = "Marie", LastName = "Tyler"});
    StudentBs.Add(new Student_B(){Id = 4, FirstName = "Bobby", MiddleName = "Stephen", LastName = "Singer"});

    var result = StudentAs.Union((IEnumerable<Object>)StudentBs);

    result.Dump();
}