Dapper 本身不支持跨数据库查询,它只是轻量级的 ORM 工具,负责把 SQL 查询结果映射到 C# 对象。真正的跨库能力取决于底层数据库是否支持、SQL 语句怎么写,以及你用的是哪种数据库环境(比如 SQL Server 的 Linked Server、PostgreSQL 的 dblink、MySQL 的 FEDERATED 引擎等)。
SQL Server 中用 Linked Server + Dapper 查询
在 SQL Server 环境下,如果已配置好 Linked Server(比如远程服务器叫 REMOTESVR,数据库叫 RemoteDB),你就可以像访问本地表一样,在 SQL 里用四部分命名法:
[ServerName].[DatabaseName].[Schema].[Table]。Dapper 只需执行这个 SQL 即可。
示例:
假设已建好 Linked Server 名为 REMOTESVR 远程数据库是 RemoteDB,表是 dbo.Users 本地数据库有 dbo.Orders 想查“本地订单 + 远程用户姓名”,SQL 可写成: SELECT o.Id, o.OrderNo, u.Name FROM dbo.Orders o INNER JOIN [REMOTESVR].[RemoteDB].[dbo].[Users] u ON o.UserId = u.Id然后用 Dapper 执行即可:
var sql = @"SELECT o.Id, o.OrderNo, u.Name
FROM dbo.Orders o
INNER JOIN [REMOTESVR].[RemoteDB].[dbo].[Users] u ON o.UserId = u.Id";
var result = conn.Query<OrderWithUserName>(sql);注意权限与性能问题
Linked Server 查询不是魔法,它依赖 SQL Server 的分布式查询能力,有几个关键点要注意:
执行账号必须在本地和远程服务器上都有足够权限(尤其是对远程库的 SELECT 权限) Linked Server 默认可能禁用 RPC 和 RPC Out,需在 SSMS 中右键 Linked Server → 属性 → 启用“RPC”和“RPC Out” 跨服务器 JOIN 很容易导致性能差——SQL Server 可能会把整张远程表拉到本地再 JOIN,建议尽量把过滤条件(WHERE)推到远程侧,或改用 OPENQUERY OPENQUERY 能让远程服务器先执行子查询,更可控,例如:SELECT * FROM OPENQUERY(REMOTESVR, 'SELECT Id, Name FROM RemoteDB.dbo.Users WHERE Status = 1')
Dapper 无法自动跨库,但可以封装多数据源
如果你不想依赖 Linked Server,也可以在应用层管理多个 DbConnection,手动组合数据:
用一个连接查本地订单:conn1.Query<order>("SELECT * FROM Orders WHERE ...")</order>
用另一个连接查远程用户:conn2.Query<user>("SELECT Id, Name FROM Users WHERE Id IN (...)")</user>
在 C# 里用 LINQ Join 或 Dictionary 做内存关联
适合数据量不大、实时性要求不高、或远程库不支持 Linked Server 的场景
其他数据库怎么办?
PostgreSQL 可用 dblink 或 postgres_fdw;MySQL 5.7+ 支持 FEDERATED 引擎(需开启);而 SQLite、SQL Server LocalDB 等则基本不支持跨库查询。Dapper 对所有这些都一视同仁——只要你的 SQL 合法、驱动支持、连接能通,它就能执行并映射。
本质上,Dapper 不关心你是查一张表、三张本地表,还是跨两个实例的五张表。它只关心:SQL 能执行、字段能匹配、类型能转换。
基本上就这些。
