我刚刚开始使用MS实体框架,并且LINQ存在以下问题。我会简化我的问题,使其更清晰;假设我在SQL Server数据库中有三个表:
我知道具有一对一关系的数据应该更好地在同一个表中,但这是一些公司数据库,并且不可能改变原始表(所以我们所有的数据都应该在单独的表中)。 / p>
现在,我想显示一个客户列表及其来自CustomerData表的数据,并通过join从CustomerData1添加一些数据列。 另一方面,我想显示一个客户列表,并通过join从其他表CustomerData2添加一些数据。
所以数据基本上都是相同的,除了在第一种情况下结果包括来自CustomerData1的一些列,在第二种情况下包括来自CustomerData2表的一些数据。
因此,我使用CustomerData表中所有相关列的属性创建了Customer类,并添加了应包含在CustomerData1中的列的属性以及应包含在CustomerData2中的属性。 每次都应包含所有列,但在第一次调用时,映射到CustomerData2表的属性将为空,在第二次调用期间,映射到CustomerData1表的属性将为空。
为此,我想创建一个函数,所以我试图像这样创建它: 函数中的输入参数是来自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
当然这不会编译,因为两个变量都在if语句中。我知道我可以在if语句中复制最后一个语句(var query3 = ...)并仅包含相关的赋值(Data1或Data2),但我不想分配映射到CustomerData表的属性两次(两次都是一次)如果声明)我也不想订购两次。
我该如何解决这个问题?我使用的是.NET 4。
答案 0 :(得分:1)
您不能预先声明匿名类型的变量,即在两个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);
我不确定Customer
是模型中的实体还是仅用于投影的类。如果它是一个实体,你必须更改最后一个代码,因为你不能投射到一个实体(基本上你需要另一个帮助类型进行投影)。