EF Core 6中实体如何从非建模跨库表获取用户全名?
EF Core 6跨库获取用户全名的几种实现方案
不是只能用关联视图,下面提供几种更灵活的实现方式,包括创建数据库函数、原生SQL查询等:
一、创建数据库函数的实现步骤
1. 在EF实体所在数据库创建标量函数
先写SQL创建跨库查询用户全名的函数,替换成你实际的数据库、表和字段名:
CREATE FUNCTION dbo.GetUserName(@UserId INT) RETURNS NVARCHAR(100) AS BEGIN DECLARE @Name NVARCHAR(100) SELECT @Name = FullName FROM [目标数据库名].[dbo].[Users] WHERE Id = @UserId RETURN ISNULL(@Name, '未知用户') END
2. 在EF Core中映射该函数
创建静态扩展类,用[DbFunction]标记对应方法:
public static class CustomDbFunctions { [DbFunction("GetUserName", Schema = "dbo")] public static string GetUserName(int userId) { // 这个方法仅用于EF Core的查询翻译,实际不会执行 throw new NotImplementedException(); } }
然后在你的DbContext的OnModelCreating方法里注册函数:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.HasDbFunction(() => CustomDbFunctions.GetUserName(default(int))); }
3. 查询时调用函数
在LINQ查询里直接调用这个静态方法,EF会自动翻译成SQL执行:
var result = await dbContext.YourEntities .Select(e => new { e.Id, e.Content, 创建人姓名 = CustomDbFunctions.GetUserName(e.CreatedBy) }) .ToListAsync();
二、无需创建数据库对象的轻量方案
如果只是少数场景使用,没必要创建函数或视图,直接用原生SQL更高效:
1. 原生SQL查询+DTO
先定义一个接收结果的DTO类:
public class EntityWithUserNameDto { public int Id { get; set; } public string Content { get; set; } public string CreatedByName { get; set; } }
然后写跨库SQL查询:
var sql = @" SELECT e.Id, e.Content, u.FullName AS CreatedByName FROM dbo.YourEntities e LEFT JOIN [目标数据库名].[dbo].[Users] u ON e.CreatedBy = u.Id WHERE e.Id = @EntityId"; var entity = await dbContext.Set<EntityWithUserNameDto>() .FromSqlRaw(sql, new SqlParameter("@EntityId", 123)) .FirstOrDefaultAsync();
2. LINQ结合跨库原生查询
也可以用EF的FromSqlRaw加载跨库的用户表数据,再和当前实体关联:
public class UserNameDto { public int Id { get; set; } public string FullName { get; set; } } // 查询关联数据 var entitiesWithNames = await dbContext.YourEntities .Join( dbContext.Set<UserNameDto>().FromSqlRaw("SELECT Id, FullName FROM [目标数据库名].[dbo].[Users]"), entity => entity.CreatedBy, user => user.Id, (entity, user) => new { entity.Id, entity.Content, CreatedByName = user.FullName } ) .ToListAsync();
三、关联视图方案(适合频繁复用场景)
如果需要多次查询带用户全名的实体数据,可以创建视图:
CREATE VIEW dbo.YourEntitiesWithUserInfo AS SELECT e.*, u.FullName AS CreatedByName, u2.FullName AS UpdatedByName FROM dbo.YourEntities e LEFT JOIN [目标数据库名].[dbo].[Users] u ON e.CreatedBy = u.Id LEFT JOIN [目标数据库名].[dbo].[Users] u2 ON e.UpdatedBy = u2.Id
然后在EF中为这个视图创建对应的实体类,直接查询视图即可,用法和普通实体完全一致。
内容的提问来源于stack exchange,提问作者jason
相关产品推荐
相关产品推荐

