gpt4 book ai didi

c# - Entity Framework 6.1.1 DbJoinExpression 获取所有左列

转载 作者:行者123 更新时间:2023-11-30 12:58:16 24 4
gpt4 key购买 nike

我正在尝试让表达式树访问者在查询某些实体时将连接添加到另一个表。如果我包含一个 .Select(),表达式会很好用投影到匿名类型的方法,并直接指定要查询的特定实体的列:

var joinEntity = expression.Target.EntityContainer.BaseEntitySets.Single(s => s.Name == "TestJoinTable");

return expression.InnerJoin(
DbExpressionBuilder.Scan(joinEntity),
(l, r) => DbExpressionBuilder.And(
DbExpressionBuilder.Equal(
DbExpressionBuilder.Property(l, "JoinId"),
DbExpressionBuilder.Property(r, "JoinId")
)
, DbExpressionBuilder.Equal(
DbExpressionBuilder.Property(r, "UserId"),
DbExpression.FromInt32(_userId)
)
)
)
.Select(exp =>
new { // these are the 3 columns from one specific entity I have called Resources
ResourceId = exp.Property("l").Property("ResourceId"),
ResourceName = exp.Property("l").Property("ResourceName"),
JoinId = exp.Property("l").Property("JoinId"),
}
);

导致此表​​达式逻辑在此特定情况下运行的 LINQ to Enties 查询是:

List<Resource> resources = db.Resources.ToList();

问题是,表达式访问者代码旨在针对许多不同的实体查询运行,而不仅仅是资源实体查询。我需要一种动态方式来从左侧实体中选择所有列。我需要指定如下内容:

.Select( exp => exp.Property("l").Property("*") )

上面的表达式无法编译。它抛出错误:No property with the name '*' is declared by the type 'ScratchDbModel.Store.Resource' .

我也试过这个,但它失败了,并出现类似的错误消息:

.Select( exp => exp.Property("l.*") )

我试过像这样只选择左边的实体:

.Select( exp => exp.Property("l") )

上面的表达式编译并看起来很有希望,直到它实际运行查询,结果是这个 SQL:

SELECT 
[Extent1].[ResourceId] AS [ResourceId],
[Extent1].[ResourceName] AS [ResourceName],
[Extent1].[JoinId] AS [JoinId]
FROM ( SELECT [l]
FROM [dbo].[Resource] AS [l]
INNER JOIN [sec].[TestJoinTable] AS [r]
ON ([l].[JoinId] = [r].[JoinId]) AND ([r].[UserId] = 2)
) AS [Extent1]

并且由于内部 SELECT 正在选择 [l]而不是 [l.*]或列名列表,查询执行失败并显示此消息:

Invalid column name 'l'.
Invalid column name 'ResourceId'.
Invalid column name 'ResourceName'.
Invalid column name 'JoinId'.

我尝试过很多不同的东西,但似乎无法弄清楚如何做到这一点。如果我离开 .Select()完全,我收到错误:

An exception of type 'System.ArgumentOutOfRangeException' occurred in EntityFramework.dll but was not handled in user code

Additional information: No property with the name 'ResourceId' is declared by the type 'Transient.rowtype[(l,ScratchDbModel.Store.Resource(Nullable=True,DefaultValue=)),(r,ScratchDbModel.Store.TestJoinTable(Nullable=True,DefaultValue=))]'.

当然,这是因为 Entity Framework 期望收到 IEnumerable<Resource> ,而不是一些多表连接结果。

有什么方法可以通用地指定“左表中的所有列”或创建某种类型的动态匿名类型或包含左实体所有列引用的动态投影?

最佳答案

要选择 property l 的所有属性,只需整体选择它:

return expression.InnerJoin(
DbExpressionBuilder.Scan(joinEntity),
(l, r) => DbExpressionBuilder.Equal(
DbExpressionBuilder.Property(l, "JoinId"),
DbExpressionBuilder.Property(r, "JoinId")
)
)
.Select(exp => exp.Property("l"));

这将自动生成查询,选择“l”拥有的所有列。

关于c# - Entity Framework 6.1.1 DbJoinExpression 获取所有左列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30431756/

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