如何用LINQ将属性名与值存入字典并实现电影ID批量映射至DTO
解决方案
1. 用字典存储属性名与对应值
两种实现方式,按需选择:
- 手动构建(固定字段场景推荐):直接把ViewModel里的电影名字段存入字典,键为属性名,值为对应名称:
var movieNameDict = new Dictionary<string, string> { { "MovieName1", viewModel.MovieName1 }, { "MovieName2", viewModel.MovieName2 }, { "MovieName3", viewModel.MovieName3 }, { "MovieName4", viewModel.MovieName4 } }; // 过滤空值,避免无效查询 var validMovieNames = movieNameDict.Where(kv => !string.IsNullOrEmpty(kv.Value)) .ToDictionary(kv => kv.Key, kv => kv.Value);
- 反射提取(多字段复用场景推荐):通过反射自动匹配符合命名规则的字段:
var movieNameProps = typeof(YourViewModel).GetProperties() .Where(p => p.Name.StartsWith("MovieName") && p.PropertyType == typeof(string)); var movieNameDict = movieNameProps.ToDictionary(p => p.Name, p => (string)p.GetValue(viewModel));
2. LINQ实现IN查询批量获取ID
提取字典里的所有有效电影名称,用EF LINQ的Contains方法实现SQL的IN逻辑,批量查询并转成名称到ID的映射字典:
var targetNames = validMovieNames.Values.Distinct().ToList(); // 等价于SQL: SELECT MovieName, MovieID FROM TBL_Movies WHERE MovieName IN (...) var nameToIdMap = await _context.TBL_Movies .Where(m => targetNames.Contains(m.MovieName)) .ToDictionaryAsync(m => m.MovieName, m => m.MovieID);
3. 将查询到的ID赋值回DTO对应字段
同样分两种方式:
- 手动赋值(直观易维护):逐个匹配名称与ID,直接赋值到DTO字段:
var dto = new MovieDetailUpdateDto { Tab_ID = viewModel.Tab_ID, MovieID1 = nameToIdMap.TryGetValue(viewModel.MovieName1, out var id1) ? id1 : null, MovieID2 = nameToIdMap.TryGetValue(viewModel.MovieName2, out var id2) ? id2 : null, MovieID3 = nameToIdMap.TryGetValue(viewModel.MovieName3, out var id3) ? id3 : null, MovieID4 = nameToIdMap.TryGetValue(viewModel.MovieName4, out var id4) ? id4 : null };
- 反射赋值(多字段场景推荐):通过字段名的命名规则自动匹配赋值:
var dto = new MovieDetailUpdateDto { Tab_ID = viewModel.Tab_ID }; foreach (var kv in validMovieNames) { var dtoPropName = kv.Key.Replace("MovieName", "MovieID"); var dtoProp = typeof(MovieDetailUpdateDto).GetProperty(dtoPropName); if (dtoProp != null && nameToIdMap.TryGetValue(kv.Value, out var movieId)) { dtoProp.SetValue(dto, movieId); } }
4. 是否可以通过SQL Join实现
可以,但仅适合需要关联TBL_Transact的场景(比如验证Tab_ID的合法性)。如果只是单纯根据名称查ID,直接用IN查询比Join更高效,因为无需关联额外表。示例Join查询:
var query = from t in _context.TBL_Transact join m in _context.TBL_Movies on t.MovieID equals m.MovieID where t.Tab_ID == viewModel.Tab_ID && targetNames.Contains(m.MovieName) select new { m.MovieName, m.MovieID }; var nameToIdMap = query.ToDictionary(m => m.MovieName, m => m.MovieID);
内容的提问来源于stack exchange,提问作者Agnib
相关产品推荐
相关产品推荐

