如何在LINQ中将查询结果声明给实体
我刚开始使用MS实体框架,但LINQ有以下问题。我会简化我的问题,让它更清楚;假设SQL Server数据库中有三个表:如何在LINQ中将查询结果声明给实体,linq,entity-framework-4,Linq,Entity Framework 4,我刚开始使用MS实体框架,但LINQ有以下问题。我会简化我的问题,让它更清楚;假设SQL Server数据库中有三个表: CustomerData(PK是CustomerId,该表还有大约二十列用于保存客户数据) CustomerData1(以一对一关系保存客户的一些数据) CustomerData2(还以一对一关系保存客户的一些数据) 我知道具有一对一关系的数据最好在同一个表中,但这是一些公司数据库,不可能更改原始表(因此我们所有的数据都应该在单独的表中) 现在,我想显示一个客户列表,其中
- CustomerData(PK是CustomerId,该表还有大约二十列用于保存客户数据)
- CustomerData1(以一对一关系保存客户的一些数据)
- CustomerData2(还以一对一关系保存客户的一些数据)
if (firstList)
{
var query1 = from obj in CustomerData
join rel in CustomerData1
on obj.CustomerId equals rel.CustomerId
select new { obj, rel };
}
if (secondList)
{
var query2 = from obj in CustomerData
join rel in CustomerData2
on obj.CustomerId equals rel.CustomerId
select new { obj, rel };
}
因此,这段代码根据输入参数为我提供了匿名类型。现在我想创建Customer对象并对其进行排序(顺序始终相同,它不依赖于输入参数)。因此,我想创建一个已订购客户的列表,并根据输入参数包含其他数据
var query3 = <previous_query_variable>.Select(f => new Customer {
Id = f.obj.CustomerId,
Name = f.obj.CustomerName,
... other columns from Customer table (a lot of them)
//and then add some additional columns based on the input parameter
Data1 = f.rel.someDataFromCustomer1, //only when firstList == true, otherwise empty
Data2 = f.rel.someDataFromCustomer2 //only when secondList == true, otherwise empty
}).OrderBy(f => f.Name); //order by customer name
var query3=。选择(f=>newcustomer{
Id=f.obj.CustomerId,
Name=f.obj.CustomerName,
…Customer表中的其他列(很多)
//然后根据输入参数添加一些附加列
Data1=f.rel.someDataFromCustomer1,//仅当firstList==true时,否则为空
Data2=f.rel.someDataFromCustomer2//仅当secondList==true时,否则为空
}).OrderBy(f=>f.Name)//按客户名称订购
当然这不会编译,因为两个变量都在if语句中。我知道我可以将最后一条语句(var query3=…)复制到两个if语句中,并且只包括相关的赋值(Data1或Data2),但我不想将映射到CustomerData表的属性赋值两次(在两个if语句中都赋值一次),也不想排序两次
我怎样才能解决这个问题?我使用的是.NET 4。您不能预先为匿名类型声明变量,即在两个if语句之前。(不支持
var query=null
之类的内容。)您必须创建一个助手类型并将其投影到其中,如下所示:
public class ProjectedCustomerData
{
public CustomerData CustomerData { get; set; }
public CustomerData1 CustomerData1 { get; set; }
public CustomerData2 CustomerData2 { get; set; }
}
然后是投影:
IQueryable<ProjectedCustomerData> resultQuery = null;
if (firstList)
{
resultQuery = from obj in CustomerData
join rel in CustomerData1
on obj.CustomerId equals rel.CustomerId
select new ProjectedCustomerData
{
CustomerData = obj,
CustomerData1 = rel
};
}
if (secondList)
{
resultQuery = from obj in CustomerData
join rel in CustomerData2
on obj.CustomerId equals rel.CustomerId
select new ProjectedCustomerData
{
CustomerData = obj,
CustomerData2 = rel
};
}
var query3 = resultQuery.Select(f => new Customer {
Id = f.CustomerData.CustomerId,
Name = f.CustomerData.CustomerName,
// ...
Data1 = f.CustomerData1.someDataFromCustomer1,
Data2 = f.CustomerData2.someDataFromCustomer2
}).OrderBy(f => f.Name);
IQueryable resultQuery=null;
如果(第一名单)
{
resultQuery=来自CustomerData中的obj
在CustomerData1中加入rel
在obj.CustomerId上等于rel.CustomerId
选择新建ProjectedCustomerData
{
CustomerData=obj,
CustomerData1=rel
};
}
如果(第二名单)
{
resultQuery=来自CustomerData中的obj
在CustomerData2中加入rel
在obj.CustomerId上等于rel.CustomerId
选择新建ProjectedCustomerData
{
CustomerData=obj,
CustomerData2=rel
};
}
var query3=resultQuery.Select(f=>newcustomer{
Id=f.CustomerData.CustomerId,
Name=f.CustomerData.CustomerName,
// ...
Data1=f.CustomerData1.someDataFromCustomer1,
数据2=f.CustomerData2.someDataFromCustomer2
}).OrderBy(f=>f.Name);
我不确定
Customer
是您模型中的一个实体,还是仅用于投影的一个类。如果它是一个实体,您必须更改最后一个代码,因为您无法投影到一个实体中(基本上您需要另一个助手类型进行投影)。您不能预先为匿名类型声明变量,即在两个If语句之前。(不支持var query=null
之类的内容。)您必须创建一个助手类型并将其投影到其中,如下所示:
public class ProjectedCustomerData
{
public CustomerData CustomerData { get; set; }
public CustomerData1 CustomerData1 { get; set; }
public CustomerData2 CustomerData2 { get; set; }
}
然后是投影:
IQueryable<ProjectedCustomerData> resultQuery = null;
if (firstList)
{
resultQuery = from obj in CustomerData
join rel in CustomerData1
on obj.CustomerId equals rel.CustomerId
select new ProjectedCustomerData
{
CustomerData = obj,
CustomerData1 = rel
};
}
if (secondList)
{
resultQuery = from obj in CustomerData
join rel in CustomerData2
on obj.CustomerId equals rel.CustomerId
select new ProjectedCustomerData
{
CustomerData = obj,
CustomerData2 = rel
};
}
var query3 = resultQuery.Select(f => new Customer {
Id = f.CustomerData.CustomerId,
Name = f.CustomerData.CustomerName,
// ...
Data1 = f.CustomerData1.someDataFromCustomer1,
Data2 = f.CustomerData2.someDataFromCustomer2
}).OrderBy(f => f.Name);
IQueryable resultQuery=null;
如果(第一名单)
{
resultQuery=来自CustomerData中的obj
在CustomerData1中加入rel
在obj.CustomerId上等于rel.CustomerId
选择新建ProjectedCustomerData
{
CustomerData=obj,
CustomerData1=rel
};
}
如果(第二名单)
{
resultQuery=来自CustomerData中的obj
在CustomerData2中加入rel
在obj.CustomerId上等于rel.CustomerId
选择新建ProjectedCustomerData
{
CustomerData=obj,
CustomerData2=rel
};
}
var query3=resultQuery.Select(f=>newcustomer{
Id=f.CustomerData.CustomerId,
Name=f.CustomerData.CustomerName,
// ...
Data1=f.CustomerData1.someDataFromCustomer1,
数据2=f.CustomerData2.someDataFromCustomer2
}).OrderBy(f=>f.Name);
我不确定Customer
是您模型中的一个实体,还是仅用于投影的一个类。如果它是一个实体,你必须改变它