在 Linq 中连接具有不同数据类型的表
Join Tables with Different DataType in Linq
我有两个表需要对表 1 和表 2 进行左外连接,但是表 1 的课程标题是 VARCHAR(1000),而表 2 的课程标题是文本数据类型。我对这两个字段都使用了 ToString(),但仍然出现错误。以下是我的加入查询:
IQueryable<joinedTable> qry=(from a in db.table1
join b in db.table2 on
new {SUBJECT=a.SUBJECT, CATALOG_NBR=a.CATALOG_NBR, COURSETITLE=a.COURSETITLE.ToString() } equals
new { SUBJECT = b.SUBJECT, CATALOG_NBR = b.CATALOG_NBR, COURSETITLE=b.COURSETITLE.ToString() } into ab
from x in ab.DefaultIfEmpty()
select new joinedTable()
{
ID=a.ID,
SUBJECT=a.SUBJECT,
CATALOG_NBR=a.CATALOG_NBR,
COURSETITLE=a.COURSETITLE,
DESCR=x.DESCR
}.AsQueryable();
错误:
"The data types varchar and text are incompatible in the equal to operator."
IQueryable<joinedTable> qry = (from a in db.table1
join b in db.table2 on
new { SUBJECT = a.SUBJECT, CATALOG_NBR = a.CATALOG_NBR, COURSETITLE = a.COURSETITLE.ToString() } equals
new { SUBJECT = b.SUBJECT, CATALOG_NBR = b.CATALOG_NBR, COURSETITLE = b.COURSETITLE.ToString() } into ab
from x in ab.DefaultIfEmpty()
select new joinedTable()
{
ID = a.ID,
SUBJECT = a.SUBJECT,
CATALOG_NBR = a.CATALOG_NBR,
COURSETITLE = a.COURSETITLE,
DESCR = x==null?"":x.DESCR
}.AsQueryable();
我不确定,但尝试一下希望它会起作用。
使用 pre-select 确保要加入的键相等:
var preselectTable1 = db.Table1.Select(row => new
{
JoinKey = new
{
Subject = row.SUBJECT,
CatalogNbr = row.CATALOG_NBR,
CourseTitle = row.COURSETITLE.ToString(),
},
... // select the other table1 properties that you want to put in your final result
});
var preselectTable2 = db.Table2.Select(row => new
{
JoinKey = new
{
Subject = row.SUBJECT,
CatalogNbr = row.CATALOG_NBR,
CourseTitle = row.COURSETITLE.ToString(),
},
... // select the other table2 properties that you want to put in your final result
});
现在两个 JoinKeys 是完全相同的类型。注意:他还没有执行查询,没有联系数据库,只是调整了查询的表达式。
每当您需要“客户及其订单”、“学校及其学生”、“来自 table1 的行及其来自 table2 的行”时,请考虑使用 overloads of GroupJoin,而不是加入。我通常使用带有参数 resultSelector 的重载,所以我可以微调我的结果。
要获取 table1 行,每行都有零个或多个匹配的 table2 行,请使用 GroupJoin
:
var result = preselectTable1.GroupJoin(preselectTable2,
table1Row => table1Row.JoinKey, // from every row in table1 get the joinKey
table2Row => table2Row.JoinKey, // from every row in table2 get the joinKey
// parameter result selector: from every row in table 1 and all rows in table2
// that have the same value for JoinKey make one new:
(table1Row, matchingTable2Rows) => new
{
// select the table1 properties that you want to use
Id = table1Row.Id,
Name = table1Row.Name,
...
matching2Items = matchingTable2Rows.Select(table2Row => new
{
// select the table2 properties that you want.
Id = table2Row.Id,
Name = table2Row.Name,
...
})
.ToList(),
});
在上面的例子中,结果似乎有点奇怪。那是因为我不知道 table1 和 table2 是什么。如果你用同样的方法得到“Customer and their Orders”,结果会很自然:
IQueryable<Customer> customers = ...
IQueryable<Order> orders = ...
var customersWithTheirOrders = customers.GroupJoin(orders,
customer => customer.Id, // from each Customer take the primary key
order => order.CustomerId, // from each order take the foreign key
(customer, ordersOfThisCustomer) => new
{
Id = customer.Id,
AddressLabel = new AddressLabel
{
Name = customer.Name,
Street = customer.Street,
City = ...
}
Orders = ordersOfThisCustomer.Select(order => new
{
Id = order.Id,
Date = order.Date,
Total = order.Total,
...
})
.ToList(),
});
除此之外,感觉“table1 项及其匹配的 table2 项”比“table1 项与匹配 table 2 item", groupjoin 的优点之一是 item1 属性只传输一次。
如果 School[10] 有 2000 名学生,只传输一次 School[10] 的数据比为 2000 名学生传输一次相同的学校数据效率更高。
如果你真的想要一个扁平的最终结果,使用SelectMany.
我有两个表需要对表 1 和表 2 进行左外连接,但是表 1 的课程标题是 VARCHAR(1000),而表 2 的课程标题是文本数据类型。我对这两个字段都使用了 ToString(),但仍然出现错误。以下是我的加入查询:
IQueryable<joinedTable> qry=(from a in db.table1
join b in db.table2 on
new {SUBJECT=a.SUBJECT, CATALOG_NBR=a.CATALOG_NBR, COURSETITLE=a.COURSETITLE.ToString() } equals
new { SUBJECT = b.SUBJECT, CATALOG_NBR = b.CATALOG_NBR, COURSETITLE=b.COURSETITLE.ToString() } into ab
from x in ab.DefaultIfEmpty()
select new joinedTable()
{
ID=a.ID,
SUBJECT=a.SUBJECT,
CATALOG_NBR=a.CATALOG_NBR,
COURSETITLE=a.COURSETITLE,
DESCR=x.DESCR
}.AsQueryable();
错误:
"The data types varchar and text are incompatible in the equal to operator."
IQueryable<joinedTable> qry = (from a in db.table1
join b in db.table2 on
new { SUBJECT = a.SUBJECT, CATALOG_NBR = a.CATALOG_NBR, COURSETITLE = a.COURSETITLE.ToString() } equals
new { SUBJECT = b.SUBJECT, CATALOG_NBR = b.CATALOG_NBR, COURSETITLE = b.COURSETITLE.ToString() } into ab
from x in ab.DefaultIfEmpty()
select new joinedTable()
{
ID = a.ID,
SUBJECT = a.SUBJECT,
CATALOG_NBR = a.CATALOG_NBR,
COURSETITLE = a.COURSETITLE,
DESCR = x==null?"":x.DESCR
}.AsQueryable();
我不确定,但尝试一下希望它会起作用。
使用 pre-select 确保要加入的键相等:
var preselectTable1 = db.Table1.Select(row => new
{
JoinKey = new
{
Subject = row.SUBJECT,
CatalogNbr = row.CATALOG_NBR,
CourseTitle = row.COURSETITLE.ToString(),
},
... // select the other table1 properties that you want to put in your final result
});
var preselectTable2 = db.Table2.Select(row => new
{
JoinKey = new
{
Subject = row.SUBJECT,
CatalogNbr = row.CATALOG_NBR,
CourseTitle = row.COURSETITLE.ToString(),
},
... // select the other table2 properties that you want to put in your final result
});
现在两个 JoinKeys 是完全相同的类型。注意:他还没有执行查询,没有联系数据库,只是调整了查询的表达式。
每当您需要“客户及其订单”、“学校及其学生”、“来自 table1 的行及其来自 table2 的行”时,请考虑使用 overloads of GroupJoin,而不是加入。我通常使用带有参数 resultSelector 的重载,所以我可以微调我的结果。
要获取 table1 行,每行都有零个或多个匹配的 table2 行,请使用 GroupJoin
:
var result = preselectTable1.GroupJoin(preselectTable2,
table1Row => table1Row.JoinKey, // from every row in table1 get the joinKey
table2Row => table2Row.JoinKey, // from every row in table2 get the joinKey
// parameter result selector: from every row in table 1 and all rows in table2
// that have the same value for JoinKey make one new:
(table1Row, matchingTable2Rows) => new
{
// select the table1 properties that you want to use
Id = table1Row.Id,
Name = table1Row.Name,
...
matching2Items = matchingTable2Rows.Select(table2Row => new
{
// select the table2 properties that you want.
Id = table2Row.Id,
Name = table2Row.Name,
...
})
.ToList(),
});
在上面的例子中,结果似乎有点奇怪。那是因为我不知道 table1 和 table2 是什么。如果你用同样的方法得到“Customer and their Orders”,结果会很自然:
IQueryable<Customer> customers = ...
IQueryable<Order> orders = ...
var customersWithTheirOrders = customers.GroupJoin(orders,
customer => customer.Id, // from each Customer take the primary key
order => order.CustomerId, // from each order take the foreign key
(customer, ordersOfThisCustomer) => new
{
Id = customer.Id,
AddressLabel = new AddressLabel
{
Name = customer.Name,
Street = customer.Street,
City = ...
}
Orders = ordersOfThisCustomer.Select(order => new
{
Id = order.Id,
Date = order.Date,
Total = order.Total,
...
})
.ToList(),
});
除此之外,感觉“table1 项及其匹配的 table2 项”比“table1 项与匹配 table 2 item", groupjoin 的优点之一是 item1 属性只传输一次。
如果 School[10] 有 2000 名学生,只传输一次 School[10] 的数据比为 2000 名学生传输一次相同的学校数据效率更高。
如果你真的想要一个扁平的最终结果,使用SelectMany.