繁体   English   中英

IEnumerable与IQueryable对象-LinQ to SQL

[英]IEnumerable vs IQueryable object - LinQ to SQL

最初,我有一个名为“ Employees”的IEnumerable对象,该对象的所有属性都映射到单个类“ Employee”。

我将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;
            }
        }
    }

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

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

但是,由于您要投影为匿名类型(尽管您将其命名为变量,但不是一个Employee对象的集合),所以在编译时您不知道类型名称,因此无法指定类型T用于IQueryable<T>

最好的解决方案是定义一个具体的类型,而不要使用anonymous on,以便您可以在编译时访问该字段。 可以使用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标准-大写驼峰式的类和小写驼峰式的变量

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM