使用 Linq/Lambda 表达式将对象组合成新模型
Combining Objects into a new model with Linq/Lambda expressions
我正在开发一个 Blazor 项目并使用 Dapper 从 SQL 数据库中提取数据。
我现在正在拉 3 tables。实体 table、专业 table 和桥梁 table 用于维护实体和专业之间的多对多关系。
我可以很好地从 SQL 中提取数据,我想合并我的数据服务中的数据并将其作为新的对象模型注入到 Blazor 组件中。
以下是模型:
实体
public class EntityModel : IEntityModel
{
public int Id { get; set; }
public int PhysicianId { get; set; }
public int PartnerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
专业
public class SpecialtyModel : ISpecialtyModel
{
public int Id { get; set; }
public string Name { get; set; }
}
桥模型
public class BridgeModel : IBridgeModel
{
public int Id1 { get; set; }
public int Id2 { get; set; }
}
我将桥梁模型中的属性设为通用,这样我就可以将它与另一座桥梁一起使用 table 我拥有多对多关系。网桥 table 只是两列 ID,link 它们各自的 table。在这种情况下 Entity.Id 和 Specialty.Id
这是我将所有信息组合成的模型:
public class CombinedModel : ICombinedModel
{
public int Id { get; set; }
public int PhysicianId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public List<ISpecialtyModel> Specialties { get; set; }
}
这是我的数据服务的内部,我在尝试将数据与 Linq 和 Lambda 表达式相结合时遇到困难。
public async Task<List<IEntityModel>> ReadEntities()
{
var entities = await _dataAccess.LoadData<EntityModel, dynamic>("dbo.spEntity_Read", new { }, "SqlDb");
return entities.ToList<IEntityModel>();
}
public async Task<List<ISpecialtyModel>> ReadSpecialties()
{
var specialties = await _dataAccess.LoadData<SpecialtyModel, dynamic>("dbo.spSpecialty_Read", new { }, "SqlDb");
return specialties.ToList<ISpecialtyModel>();
}
public async Task<List<IBridgeModel>> ReadEntitySpecialtyBridge()
{
var bridge = await _dataAccess.LoadData<BridgeModel, dynamic>("dbo.spEntitySpecialty_Read", new { }, "SqlDb");
return bridge.ToList<IBridgeModel>();
}
public async Task<List<ICombinedModel>> CombineData()
{
var entities = await ReadEntities();
var specialties = await ReadSpecialties();
var bridge = await ReadEntitySpecialtyBridge();
//var combined = (from e in entities
// join b in bridge on e.Id equals b.Id1
// join s in specialties on b.Id2 equals s.Id
// select new CombinedModel()
// {
// Id = e.Id,
// PhysicianId = e.PhysicianId,
// FirstName = e.FirstName,
// LastName = e.LastName,
// Specialties = new List<ISpecialtyModel>()
// });
var combined = (from e in entities
select new CombinedModel
{
Id = e.Id,
PhysicianId = e.PhysicianId,
FirstName = e.FirstName,
LastName = e.LastName,
Specialties = specialties.Where(s => )
}
);
return combined.ToList<ICombinedModel>();
这就是我卡住的地方。我如何编写此 Linq 查询以将此数据合并到新模型中?
我能够将数据传递到 razor 组件,但我没有正确组合它,这就是我卡住的地方。
我希望有人能对此事有所了解。感谢您抽出宝贵时间查看此内容,非常感谢。
非常感谢,
塞萨尔
如果您想在本地处理(在服务器上执行应该消除从数据库中拉取 bridge
的需要,并且如果 bridge
包含与 [=14] 无关的记录=] 可能会产生大量不必要的数据流量)那么您只需要通过给定实体的正确 bridge
记录过滤 specialties
:
var combined = (from e in entities
select new CombinedModel {
Id = e.Id,
PhysicianId = e.PhysicianId,
FirstName = e.FirstName,
LastName = e.LastName,
Specialties = specialties.Where(s => bridge.Where(b => b.Id1 == e.Id).Select(b => b.Id2).Contains(s.Id)).ToList()
});
根据 specialties
和 entities
的大小,可能值得 pre-process bridge
提高给定实体的访问效率(Where
是 O(n) 所以 specialties.Where
x bridge.Where
是 O(n*m)):
var bridgeDict = bridge.GroupBy(b => b.Id1).ToDictionary(bg => bg.Key, bg => bg.Select(b => b.Id2).ToHashSet());
var combined = (from e in entities
let eBridge = bridgeDict[e.Id]
select new CombinedModel {
Id = e.Id,
PhysicianId = e.PhysicianId,
FirstName = e.FirstName,
LastName = e.LastName,
Specialties = specialties.Where(s => eBridge.Contains(s.Id)).ToList()
});
我正在开发一个 Blazor 项目并使用 Dapper 从 SQL 数据库中提取数据。 我现在正在拉 3 tables。实体 table、专业 table 和桥梁 table 用于维护实体和专业之间的多对多关系。
我可以很好地从 SQL 中提取数据,我想合并我的数据服务中的数据并将其作为新的对象模型注入到 Blazor 组件中。
以下是模型:
实体
public class EntityModel : IEntityModel
{
public int Id { get; set; }
public int PhysicianId { get; set; }
public int PartnerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
专业
public class SpecialtyModel : ISpecialtyModel
{
public int Id { get; set; }
public string Name { get; set; }
}
桥模型
public class BridgeModel : IBridgeModel
{
public int Id1 { get; set; }
public int Id2 { get; set; }
}
我将桥梁模型中的属性设为通用,这样我就可以将它与另一座桥梁一起使用 table 我拥有多对多关系。网桥 table 只是两列 ID,link 它们各自的 table。在这种情况下 Entity.Id 和 Specialty.Id
这是我将所有信息组合成的模型:
public class CombinedModel : ICombinedModel
{
public int Id { get; set; }
public int PhysicianId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public List<ISpecialtyModel> Specialties { get; set; }
}
这是我的数据服务的内部,我在尝试将数据与 Linq 和 Lambda 表达式相结合时遇到困难。
public async Task<List<IEntityModel>> ReadEntities()
{
var entities = await _dataAccess.LoadData<EntityModel, dynamic>("dbo.spEntity_Read", new { }, "SqlDb");
return entities.ToList<IEntityModel>();
}
public async Task<List<ISpecialtyModel>> ReadSpecialties()
{
var specialties = await _dataAccess.LoadData<SpecialtyModel, dynamic>("dbo.spSpecialty_Read", new { }, "SqlDb");
return specialties.ToList<ISpecialtyModel>();
}
public async Task<List<IBridgeModel>> ReadEntitySpecialtyBridge()
{
var bridge = await _dataAccess.LoadData<BridgeModel, dynamic>("dbo.spEntitySpecialty_Read", new { }, "SqlDb");
return bridge.ToList<IBridgeModel>();
}
public async Task<List<ICombinedModel>> CombineData()
{
var entities = await ReadEntities();
var specialties = await ReadSpecialties();
var bridge = await ReadEntitySpecialtyBridge();
//var combined = (from e in entities
// join b in bridge on e.Id equals b.Id1
// join s in specialties on b.Id2 equals s.Id
// select new CombinedModel()
// {
// Id = e.Id,
// PhysicianId = e.PhysicianId,
// FirstName = e.FirstName,
// LastName = e.LastName,
// Specialties = new List<ISpecialtyModel>()
// });
var combined = (from e in entities
select new CombinedModel
{
Id = e.Id,
PhysicianId = e.PhysicianId,
FirstName = e.FirstName,
LastName = e.LastName,
Specialties = specialties.Where(s => )
}
);
return combined.ToList<ICombinedModel>();
这就是我卡住的地方。我如何编写此 Linq 查询以将此数据合并到新模型中?
我能够将数据传递到 razor 组件,但我没有正确组合它,这就是我卡住的地方。
我希望有人能对此事有所了解。感谢您抽出宝贵时间查看此内容,非常感谢。
非常感谢, 塞萨尔
如果您想在本地处理(在服务器上执行应该消除从数据库中拉取 bridge
的需要,并且如果 bridge
包含与 [=14] 无关的记录=] 可能会产生大量不必要的数据流量)那么您只需要通过给定实体的正确 bridge
记录过滤 specialties
:
var combined = (from e in entities
select new CombinedModel {
Id = e.Id,
PhysicianId = e.PhysicianId,
FirstName = e.FirstName,
LastName = e.LastName,
Specialties = specialties.Where(s => bridge.Where(b => b.Id1 == e.Id).Select(b => b.Id2).Contains(s.Id)).ToList()
});
根据 specialties
和 entities
的大小,可能值得 pre-process bridge
提高给定实体的访问效率(Where
是 O(n) 所以 specialties.Where
x bridge.Where
是 O(n*m)):
var bridgeDict = bridge.GroupBy(b => b.Id1).ToDictionary(bg => bg.Key, bg => bg.Select(b => b.Id2).ToHashSet());
var combined = (from e in entities
let eBridge = bridgeDict[e.Id]
select new CombinedModel {
Id = e.Id,
PhysicianId = e.PhysicianId,
FirstName = e.FirstName,
LastName = e.LastName,
Specialties = specialties.Where(s => eBridge.Contains(s.Id)).ToList()
});