gpt4 book ai didi

c# - 如何使用 Linq 或 Lambda 连接一对多表并将扁平化结果投影到匿名类型

转载 作者:行者123 更新时间:2023-11-30 21:42:36 25 4
gpt4 key购买 nike

我有 3 个由外键链接的表:ChangeSet、ObjectChanges、PropertyChanges。这些表彼此之间具有一对多关系。我需要加入并投影并将结果扁平化为匿名类型。

我们在数据层使用 Entity Framework,我基本上需要使用 linq 进行以下查询。

select c.Id as ChangeSetId,
c.Timestamp,
c.Author_Id,
u.Name as [User],
o.id as ObjectChangeId,
o.TypeName,
o.ObjectReference as EntityId,
o.DisplayName,
p.Id as PropertyChangeId,
p.PropertyName,
p.ChangeType,
p.OriginalValue,
p.Value  
from ChangeSets c
inner join ObjectChanges o
on c.Id = o.ChangeSetId
left join PropertyChanges p
on p.ObjectChangeId = o.Id
inner join Users u
on u.Id = c.Author_Id
order by c.id desc

有问题的方法看起来像这样:

GetAllWhereExpression(Expression<Func<ChangeSet, bool>> expression)

这种情况下的表达式很可能是一个 Where o.EntityId = [Some Value] and c.TimeStamp > X and < Y。

我非常接近我在 linq 中的感受,但无法弄清楚如何注入(inject)表达式:(.GetRepository().Entities 基本上是 DbSet)

var foo = from c in _uow.GetRepository<ChangeSet>().Entities
join o in _uow.GetRepository<ObjectChange>().Entities on c.Id equals o.ChangeSetId
join p in _uow.GetRepository<PropertyChange>().Entities on o.Id equals p.ObjectChangeId
where expression // This Line Not Valid
select new
{
ChangeSetId = c.Id,
Timestamp = c.Timestamp,
User = c.User.DisplayName,
EntityType = o.TypeName,
EntityValue = o.DisplayName,
Property = p.PropertyName,
OldValue = p.OriginalValue,
NewValue = p.Value
};

我更喜欢使用 Lambda 语法,但我不知道如何构建它。我知道我需要 SelectMany 来投影和展平结果,但我不知道如何在子集合的匿名类型中使用它们:

var queryable = _uow.GetRepository<ChangeSet>().Entities // This is basically the DbSet<ChangeSet>()
.Where(expression)
.SelectMany(c => new
{
ChangeSetId = c.Id,
Timestamp = c.Timestamp,
User = c.User.DisplayName,
EntityType = c.ObjectChanges.SelectMany(o => o.TypeName), //Doesn't work, turns string into char array
//PropertyName = c. this would be a 1 to many on the entity
}
)

我如何制作 linq 以产生与 sql 查询基本相同的结果?

最佳答案

这是它在方法语法中的样子。

_uow.GetRepository<ChangeSet>().Entities
.Where(expression)
.Join(_uow.GetRepository<ObjectChanges>().Entities, cs => cs.Id, oc => oc.ChangeSetId,
(cs, oc) => new { cs, oc })
.Join(_uow.GetRepository<PropertyChanges>().Entities, outer => outer.oc.Id, pc => pc.ObjectChangeId,
(outer, pc) => new { cs = outer.cs, oc = outer.cs, pc })
.Join(_uow.GetRepository<User>().Entities, outer => outer.cs.Author_Id, u => u.Id,
(outer, u) => new {
ChangeSetId = outer.cs.Id,
Timestamp = outer.cs.Timestamp,
User = u.DisplayName,
EntityType = outer.oc.TypeName,
EntityValue = outer.oc.DisplayName,
Property = outer.pc.PropertyName,
OldValue = outer.pc.OriginalValue,
NewValue = outer.pc.Value
})

关于c# - 如何使用 Linq 或 Lambda 连接一对多表并将扁平化结果投影到匿名类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42430915/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com