You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# Linq查询:选择全部列并重命名重复列

Linq连接表时重复列的通用重命名方案

Linq原生语法里没有直接实现“全选两表所有字段并自动重命名重复项”的功能——你当前的查询select entry只能返回Utenti实体,自然会丢失AnagraficaUtenti的重复列。不过可以通过以下两种通用方式避免逐个手写字段:

方案一:用反射动态合并字段(返回动态类型)

写一个通用的扩展方法,通过反射读取两个实体的所有属性,给重复属性名加上表前缀后合并到动态对象中:

public static dynamic MergeEntitiesWithPrefix<T1, T2>(T1 entity1, string prefix1, T2 entity2, string prefix2)
{
    var expandoDict = (IDictionary<string, object>)new ExpandoObject();

    // 添加第一个实体的所有属性,附带指定前缀
    foreach (var prop in typeof(T1).GetProperties())
    {
        expandoDict[$"{prefix1}{prop.Name}"] = prop.GetValue(entity1);
    }

    // 添加第二个实体的所有属性,附带指定前缀
    foreach (var prop in typeof(T2).GetProperties())
    {
        expandoDict[$"{prefix2}{prop.Name}"] = prop.GetValue(entity2);
    }

    return expandoDict;
}

然后修改你的查询,直接调用这个方法合并两个实体:

var list = (
    from au in context.AnagraficaUtenti
    join ut in context.Utenti on au.CodiceUtente equals ut.CodiceUtente
    select MergeEntitiesWithPrefix(au, "AnagraficaUtenti", ut, "Utenti")
)
.AsEnumerable() // 注意:EF无法将反射逻辑转换为SQL,需要先拉取数据到内存处理
.ToList();

优缺点

  • 优势:完全不用手写字段,适配任意两个实体的合并
  • 劣势:返回动态类型,编译时没有类型检查,大数据量下内存处理性能受限

方案二:用DTO+映射工具实现强类型合并

如果需要强类型的结果,先定义包含所有字段的DTO类,重命名重复列:

public class UtenteAnagraficaCombinedDto
{
    // AnagraficaUtenti的字段
    public int CodiceUtente { get; set; }
    public string NameAnagraficaUtenti { get; set; }
    public string SurnameAnagraficaUtenti { get; set; }
    // 其他AnagraficaUtenti字段...

    // Utenti的字段
    public string NameUtenti { get; set; }
    public string SurnameUtenti { get; set; }
    // 其他Utenti字段...
}

然后用AutoMapper配置映射规则(只需配置一次重复字段,其他同名字段可自动映射):

var mapperConfig = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<(AnagraficaUtenti Au, Utenti Ut), UtenteAnagraficaCombinedDto>()
        .ForMember(dest => dest.NameAnagraficaUtenti, opt => opt.MapFrom(src => src.Au.Name))
        .ForMember(dest => dest.SurnameAnagraficaUtenti, opt => opt.MapFrom(src => src.Au.Surname))
        .ForMember(dest => dest.NameUtenti, opt => opt.MapFrom(src => src.Ut.Name))
        .ForMember(dest => dest.SurnameUtenti, opt => opt.MapFrom(src => src.Ut.Surname));
});
var mapper = mapperConfig.CreateMapper();

最后修改查询,先拉取两个实体的匿名对象,再映射到DTO:

var list = (
    from au in context.AnagraficaUtenti
    join ut in context.Utenti on au.CodiceUtente equals ut.CodiceUtente
    select new { Au = au, Ut = ut }
)
.AsEnumerable()
.Select(item => mapper.Map<UtenteAnagraficaCombinedDto>(item))
.ToList();

优缺点

  • 优势:强类型安全,编译时可检查,性能更稳定
  • 劣势:需要提前定义DTO类,第一次配置映射规则

总结

Linq本身没有原生的“全选+自动重命名”语法,但通过反射动态合并或DTO+映射工具,能实现不用逐个手写字段的通用解决方案。

内容的提问来源于stack exchange,提问作者Alessandro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 21:45:32