IEnumerable vs IQueryable对象 - LinQ to SQL

时间:2015-09-17 18:55:42

标签: c# linq iqueryable

起初我有一个名为"员工"的IEnumerable对象。将其所有属性映射到单个类"员工"。

我将IEnumerable对象Employee传递给私有方法,该方法解析了属性并将其映射到数据表。

   private void createEmployeesDataTable(IEnumerable<Employee> Employees)
    {
    .... stuff here to define the datatable ....

       foreach (var elem in Employees)
       {
           var row = dataTable.NewRow();
           row["Name"] = elem.JobTitle;
           row["Address"] = elem.Address;
           row["Phone"] = elem.Phone;
           row["DateOfHire"] = elem.HireDate;
           dataTable.Rows.Add(row);
       }
    }

像魅力一样工作。

现在我有一堆类,映射到数据库和IQueryable对象Employees。代码很简单。

    DataContext db = new DataContext(System.Configuration.ConfigurationManager.ConnectionStrings["employeeDB"].ConnectionString);
    Table<Employee> Emp = db.GetTable<Employee>();
    Table<Address> Add = db.GetTable<Address>();
    Table<BusinessEntityAddress> BE = db.GetTable<BusinessEntityAddress>();
    Table<Phone> Phone = db.GetTable<Phone>();
    Table<State> State = db.GetTable<State>();

    var Employees =
        from Employi in Emp
        join PhoneNumber in Phone on Employi.BusinessEntityID equals PhoneNumber.BusinessEntityID
        join BusEntity in BE on Employi.BusinessEntityID equals BusEntity.BusinessEntityID
        join Addy in Add on BusEntity.AddressID equals Addy.AddressID
        join StProv in State on Addy.StateProvinceID equals StProv.StateProvinceID
        where Employi.HireDate > userInputLimit
        select new {DateOfHire = Employi.HireDate, Address = Addy.AddressLine1 + Addy.City + StProv.StateProvinceCode + Addy.PostalCode,
                    Phone = PhoneNumber.PhoneNumber, Name = Employi.JobTitle};

现在我将此对象传递给私有方法,以创建数据表,除了我将其作为匿名类型的IQueryable传递。原因是,我的对象现在具有从多个类派生的属性,而不再来自单个员工类: -

private void createEmployeesDataTable(IQueryable Employees)
        {
.... how can I still access all of its properties and bind it to the datatable?? .... 
}

当我在IQueryable Employees对象上放置断点时,我可以看到它正确存储了所有属性名称和值。但我似乎无法通过代码访问它们....

我班上的一个样本: -

 [Table(Name="HumanResources.Employee")]
    public class Employee
    {
        private int _BusinessEntityID;
        [Column(IsPrimaryKey = true, CanBeNull=false, Storage = "_BusinessEntityID")]
        public int BusinessEntityID
        {
            get
            {
                return this._BusinessEntityID;
            }
            set
            {
                this._BusinessEntityID = value;
            }

        }

        private string _JobTitle;
        [Column(Storage = "_JobTitle", CanBeNull=false, DbType="nvarchar(50) NOT NULL")]
        public string JobTitle
        {
            get
            {
                return this._JobTitle;
            }
            set
            {
                this._JobTitle = value;
            }
        }


        private DateTime _HireDate;
        [Column(Storage = "_HireDate", CanBeNull=false)]
        public DateTime HireDate
        {
            get
            {
                return this._HireDate;
            }
            set
            {
                this._HireDate = value;
            }
        }
    }

1 个答案:

答案 0 :(得分:4)

  

当我在IQueryable Employees对象上放置断点时,我可以看到它正确存储了所有属性名称和值。但我似乎无法通过代码访问它们。

那是因为非泛型 IQueryable接口对底层类型一无所知。您必须使用通用版本(IQueryable<T>)才能在设计时查看项目的属性。

但是,既然您正在投射到匿名类型(而不是Employee个对象的集合,尽管您已将其命名为变量),那么您不必#&# 39;在编译时知道类型名称,因此您无法指定要用于T的类型IQueryable<T>

最佳解决方案是定义具体类型而不是使用匿名,以便您可以在编译时访问该字段。您可以使用dynamic,但是您将属性绑定延迟到运行时并且在编译时不会捕获任何错误。

类定义类似于:

public class EmployeeView
{
    public DateTime DateOfHire {get; set;}
    public string AddressLine1 {get; set;}
    public string City {get; set;}
    public string StateProvinceCode {get; set;}
    public string PostalCode {get; set;}
    public string Phone {get; set;}
    public string Name {get; set;}
}

您的预测将是:

select new EmployeeView {
    DateOfHire = Employi.HireDate, 
    AddressLine1 = Addy.AddressLine1,
    City = Addy.City,
    StateProvinceCode = StProv.StateProvinceCode,
    PostalCode = Addy.PostalCode,
    Phone = PhoneNumber.PhoneNumber, 
    Name = Employi.JobTitle};

现在您可以在:

中指定类型
private void CreateEmployeesDataTable(IEnumerable<EmployeeView> employees)
{
    .... 
}

请注意,我已将套管更改为.NET标准 - 具有大写驼峰案例的类和具有小写驼峰案例的变量