我正在基于DevForce的应用程序中编写POCO类,该应用程序具有许多命名查询,我无法弄清楚如何从命名查询中访问实体管理器。
我已从我们的实体经理部分内部放置缩短的代码,如下所示:
public partial class BearPawEntities
{
public EntityQuery<OrderView3> OrderView3s()
{
return new EntityQuery<OrderView3>("OrderView3s", this);
}
}
这是我在编写较重的查询之前尝试使其工作的基本内容之一:
[EnableClientAccess]
public class PocoServiceProvider
{
public PocoServiceProvider() { }
public IQueryable<OrderView3> GetOrderView3s()
{
var currentUser = new EntityQuery<User>().Include(u => u.Role.RoleCheckPoints).Include(u => u.CoveringForUsers)
.FirstOrDefault(u => u.UserName == System.Threading.Thread.CurrentPrincipal.Identity.Name);
List<OrderView3> orderView3s = new List<OrderView3>();
for (int i = 1; i < 150; i++)
{
orderView3s.Add(new OrderView3()
{
Id = i,
CustomerCode = $"Customer {i}",
Invoices = i
});
}
return orderView3s.AsQueryable();
}
...
}
如果我删除代码以获取当前用户,那么我的示例有效,我将列表返回给客户端,但每当我尝试调用新的EntityQuery&lt;&gt; function我得到一个带有详细信息的例外{&#34;此查询没有EntityManager&#34;}。
我已经尝试将EntityManager作为参数传递,但后来我被告知它不可序列化(我预期)。我在BearPawEntities类中的代码上设置了query.EntityManager属性,但在我看来它更能让你在需要时使用不同的管理器,而不是将它传递给查询。
我也尝试过在DevForce文档中的示例中看到的扩展方法方法。
在这一点上,我感到难过,并希望得到任何帮助!
非常感谢提前
利
答案 0 :(得分:0)
DevForce在“客户端”和“服务器端”之间保持非常严格的区别,并且不会将客户端EntityManager
传递给服务器。当您看到服务器端EntityManager
,由DevForce注入方法参数或属性时,这是为该单一目的创建的EM的新实例。
这并不意味着您无法创建自己的新实例,只需要注意如何创建它。当DF创建服务器端EM时,它被认为已经过身份验证,因此不会通过IEntityLoginManager
,并且它还使用简单的方法调用EntityServer
而不是WCF。根据您的实现,身份验证问题可能很棘手(自定义组合上下文可以帮助解决此问题),但您还应该使用EntityServiceOption.UseLocalService
选项设置EM以避免WCF开销。
命名查询与其他查询的工作流程略有不同。通常,您可以使用EntityServerQueryInterceptor
来控制授权和过滤,但在拦截器之前调用命名查询方法。这意味着如果您需要使用用户的身份来构建/执行查询,授权将“延迟”执行,可能会晚于需要执行。
此解决方法可能是在IPrincipal
实施中使用自定义IEntityLoginManager
,以确保直接从帖子的CurrentPrincipal
中获取授权查询(和保存)所需的所有信息,DF将始终为请求设置。这样做可以避免每次执行查询时都必须重新查询用户信息。
答案 1 :(得分:0)
如果命名查询(或类/ etc)使用[RequiresAuthentication]修饰,我认为拥有一个假定它经过身份验证的EM就可以了。我相信所有的缺失都是在命名查询中创建一个新的EM。
我知道线程的CurrentPrincipal已经填充了所需的自定义IPrincipal(因为我在与OP相同的项目上工作),这对于服务器方法委托来说效果很好。除了那些自动注入EM之外,这似乎没有太大的不同。