我将使用 OData(WebAPI 和 EF) 来查询数据库。现在,我需要将三个表“合并”成一个结果。
我有 3 张表和一个接口,看起来像这样:
有没有一种方法可以将三个表合并为一个
我想将这三个表合并到一个
我有 3 张表和一个接口,看起来像这样:
public class Authority : IAssociationEntity
{
public string Name { get; set; }
public int AuthorityId { get; set; }
}
public class Company : IAssociationEntity
{
public string Name { get; set; }
public int CompanyId { get; set; }
}
public class Organization : IAssociationEntity
{
public string Name { get; set; }
public int OrganizationId { get; set; }
}
public interface IAssociationEntity
{
string Name { get; set; }
}
正如您所看到的,这三个表之间存在明显的相似之处,但由于某些原因它们需要保持在不同的表中。我需要做的是使用分页并按名称搜索所有三个表,并将它们呈现在同一个列表中供用户使用。
我需要的SQL语句应该类似于以下内容:
SELECT TOP 4 a.* FROM
(
SELECT CompanyID, Name from Company WHERE Name = 'Bob'
UNION
SELECT OrganizationID, Name from Organization WHERE Name = 'Bob'
UNION
SELECT AuthorityID, Name from Authority WHERE Name = 'Bob'
) AS a
有没有一种方法可以将三个表合并为一个
IQueryable
?我想将这三个表合并到一个
IQueryable<IAssociationEntity>
中。我确实需要使用接口(或可能是基类),并以IQueryable
的形式获取结果,以便在我的OData实现中使用。像这样的东西,但它不能编译:var query = db.Companies
.Concat(db.Organizations)
.Concat(db.Authorities);
IQueryable<IAssociationEntity> mergedTables = query.Cast<IAssociationEntity>();
// Here is an EXAMPLE usage.
// What I really need is to return the IQueryable<IAssociationEntity> for my OData.
var result = mergedTables.Where(x => x.Name == "Bob").OrderBy(x => x.Name).Skip(2).Take(10);
以下是我对OData控制器的使用:
public class AssociationController : ODataController
{
[EnableQuery]
public override IQueryable<IAssociationEntity> Get(ODataQueryOptions<IAssociationEntity> q)
{
// return my IQueryable here...
}
}
毋庸置疑,在创建IQueryable
时,我不希望将整个表格都读入内存中。实际上,由于这三个表格中的某些行数达到了数百万,我确实需要使用分页功能。
最终解决方案如下:
var query = db.Companies.Select(x => new AssociationEntity { Name = x.Name })
.Concat(db.Organizations.Select(x => new AssociationEntity { Name = x.Name }))
.Concat(db.Authorities.Select(x => new AssociationEntity { Name = x.Name }));
return query;
当执行可查询对象时:
_query.Where(x => x.Name.Contains("M")).OrderBy(x => x.Name).Skip(10).Take(50).ToList();
生成的 SQL:
SELECT
[UnionAll2].[C1] AS [C1],
[UnionAll2].[Name] AS [C2]
FROM (SELECT
1 AS [C1],
[Extent1].[Name] AS [Name]
FROM [dbo].[Company] AS [Extent1]
WHERE [Extent1].[Name] LIKE N'%M%'
UNION ALL
SELECT
1 AS [C1],
[Extent2].[Name] AS [Name]
FROM [dbo].[Organization] AS [Extent2]
WHERE [Extent2].[Name] LIKE N'%M%'
UNION ALL
SELECT
1 AS [C1],
[Extent3].[Name] AS [Name]
FROM [dbo].[Authority] AS [Extent3]
WHERE [Extent3].[Name] LIKE N'%M%') AS [UnionAll2]
ORDER BY [UnionAll2].[Name] ASC
OFFSET 10 ROWS FETCH NEXT 50 ROWS ONLY
WHERE Name LIKE '%Bob%'
,而另一个地方却使用了Where(x => x.Name == "Bob")
?为什么呢? - Sampath