c# - 用一条 LINQtoSQL 语句返回不同的对象

标签 c# asp.net linq linq-to-sql

我有一个由 Employee 和 Student 实现的 IPerson。我真正想要的是您在下面看到的。一个 LINQ 语句来获取每种类型的 IPerson。在我调用该方法之前,这非常有效;)。

我为什么会收到错误是有道理的,但我真的很难找到一种合适的方法从数据库中提取所有 IPerson 对象并避免在我的应用程序中放置 switch 语句。

public IQueryable<IPerson> getPersons() {

        // gives Types in Union or Concat have different members assigned error

        var people = from p in db.Persons select p;

        var students = (from s in people
                        where s.TypeId == (int)PersonType.Student
                        select new Student
                        {
                            Id = s.Id,
                            Age = s.Age.GetValueOrDefault(0),
                            Name = s.Name,
                            Major = s.Student.Major ?? "None",
                            CreditHours = s.Student.CreditHours.GetValueOrDefault(0),
                            PersonType = (PersonType)s.TypeId
                        }).Cast<IPerson>();
        var employees = (from e in people
                        where e.TypeId == (int)PersonType.Employee
                        select new Employee
                        {
                            Id = e.Id,
                            Age = e.Age.GetValueOrDefault(0),
                            Name = e.Name,
                            PersonType = (PersonType)e.TypeId,
                            Salary = e.Employee.Salary.GetValueOrDefault(0)
                        }).Cast<IPerson>();

        return students.Concat<IPerson>(employees);
        //return (students.ToList()).Concat<IPerson>(employees.Cast<IPerson>().ToList()).AsQueryable<IPerson>();
    }

上面,有一个被注释掉的 return 语句 - 它本质上执行了一个 .ToList() 并放弃了整个延迟执行的事情,创建了 2 个 SQL 语句 - 不理想。

最佳答案

这个怎么样:

public IQueryable<IPerson> getPersons() {

    // gives Types in Union or Concat have different members assigned error

    var people = from p in db.Persons select p;

    return (from s in people
                    where s.TypeId == (int)PersonType.Student
                    select new Student
                    {
                        Id = s.Id,
                        Age = s.Age.GetValueOrDefault(0),
                        Name = s.Name,
                        Major = s.Student.Major ?? "None",
                        CreditHours = s.Student.CreditHours.GetValueOrDefault(0),
                        PersonType = (PersonType)s.TypeId
                    }).Cast<IPerson>().Union((from e in people
                        where e.TypeId == (int)PersonType.Employee
                        select new Employee
                        {
                            Id = e.Id,
                            Age = e.Age.GetValueOrDefault(0),
                            Name = e.Name,
                            PersonType = (PersonType)e.TypeId,
                            Salary = e.Employee.Salary.GetValueOrDefault(0)
                        }).Cast<IPerson>());
}

它并没有好多少,但您只需一个电话就可以搞定。或者,我会做的是这样的:

public IPerson GetPerson(Person p) //I'm guessing that the objects in collection db.Persons is of type Person
{
    IPerson ret;
    switch(p.TypeId)
    {
        case (int)PersonType.Student: ret = .......break;
        case (int)PersonType.Employee: ret = ......break;
    }
    return ret;
}

public IQueryable<IPerson> getPersons() {
    return (from p in db.Persons select p).ToList().Select(p => GetPerson(p)).AsQueryable();
}

但是你又一次得到了 switch 语句。此外,如果您不喜欢在数据库上执行 ToList() (如果我没记错的话,LinqToSQL 不支持使用带有变量的构造函数的函数),您可以尝试添加方法 GetPerson (我可能会重命名它)到LinqToSQL 生成的 Person 类(部分类),但我不确定这是合法的。

但是我不知道如何在不使用 switch 的情况下使用来自 getPersons 的 IQueryable。

关于c# - 用一条 LINQtoSQL 语句返回不同的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2319847/

相关文章:

C# LINQ 更新项 List<string>

c# - 通用 c# 循环(分区/排序)队列

c# - 如何通过局域网传输字符串?

c# - C# 中的 Voldemort 类型

c# - 使用MediaElement C#asp.net网站播放mp3文件

c# - 指定的参数超出有效值范围。参数名称 : value

c# - 如何将泛型类型指定为泛型方法中的限制

c# - IdSrv4 - 访问 token 验证器端点

asp.net - Handles 子句需要在包含类型或其基本类型之一中定义的 WithEvents 变量

c# - 在 LINQ 中加入多个 where 子句作为 OR 而不是 AND