Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# d这些对于报告的数据是实用的。涉及大量行的查询会导致并等待大量锁,另外还会导致来自数据库服务器的大量I/O请求。排队有助于确保很多这样的事情不会一下子就被踢开。运行的查询越多,它们之间的相互干扰(以及其他查询)就越多,从而加剧了性能问题_C#_Entity Framework_Linq - Fatal编程技术网

C# d这些对于报告的数据是实用的。涉及大量行的查询会导致并等待大量锁,另外还会导致来自数据库服务器的大量I/O请求。排队有助于确保很多这样的事情不会一下子就被踢开。运行的查询越多,它们之间的相互干扰(以及其他查询)就越多,从而加剧了性能问题

C# d这些对于报告的数据是实用的。涉及大量行的查询会导致并等待大量锁,另外还会导致来自数据库服务器的大量I/O请求。排队有助于确保很多这样的事情不会一下子就被踢开。运行的查询越多,它们之间的相互干扰(以及其他查询)就越多,从而加剧了性能问题,c#,entity-framework,linq,C#,Entity Framework,Linq,过度使用async。EF支持async操作,有助于在运行可能繁重的查询时使web服务器之类的东西更具响应性。不幸的是,许多开发人员认为这会使查询“更快”,或者它们应该是一致的,并且在任何地方都使用异步操作。没有,他们也不应该。异步查询名义上比同步查询慢,并且应该用于需要花费更长时间的查询,从而释放web服务器在等待时为其他请求提供服务的空间async不是性能提升,在调查性能问题时不应作为默认建议。在只需要花费更长的时间就可以切换到查询之前,消除上述所有场景 要真正了解EF和性能问题,熟悉SQL评

过度使用
async
。EF支持
async
操作,有助于在运行可能繁重的查询时使web服务器之类的东西更具响应性。不幸的是,许多开发人员认为这会使查询“更快”,或者它们应该是一致的,并且在任何地方都使用异步操作。没有,他们也不应该。异步查询名义上比同步查询慢,并且应该用于需要花费更长时间的查询,从而释放web服务器在等待时为其他请求提供服务的空间
async
不是性能提升,在调查性能问题时不应作为默认建议。在只需要花费更长的时间就可以切换到查询之前,消除上述所有场景

要真正了解EF和性能问题,熟悉SQL评测有很大帮助。这将捕获EF执行的所有查询,您可以查找任何奇怪的额外查询或“繁重”查询。(行命中率高或执行时间慢)即使测试看起来足够快,也应该检查行“接触”率高的查询。如果其中一些操作同时启动,或者在负载下与其他操作竞争锁,则这些操作在生产中可能会出现问题

编辑:对于订单和订单类型示例:


例如,正如您所说,我们有一个Order表和一个OrderType表,每个表都有自己的DBSet。现在我们想加入它们,并在EF中从中获得一个新模型,以在我们的LINQ表达式(OrderJoinTable)中引用,这是如何实现的请说明如何在EF中创建此模型

我们有一个指向订单表的订单实体和一个指向订单类型表的订单类型实体。在您的示例中,Order和OrderType都有数据库集。我假设Order表包含OrderType、OrderTypeId的FK

初始实体:

public class Order
{
   [Key]
   public int OrderId { get; set; }
   public int OrderTypeId { get; set; }
   public string OrderNumber { get; set; }
   /* Other order fields... */
}

public class OrderType
{
   [Key]
   public int OrderTypeId { get; set; }
   public string Name { get; set; }
}
在DbContext中,有两个数据库集:

public DbSet<Order> Orders { get; set; }
public DbSet<OrderType> OrderTypes { get; set; }
通过设置此导航属性,EF具备了构建查询所需的全部功能,可以在查询订单时返回订单类型详细信息。您仍然可能有一个OrderType数据库集,因为我们希望查找要分配给查找列表的订单类型,并与订单关联;但是,对于像订单行这样只作为订单的一部分存在的东西,它们不需要数据库集,只需要通过导航属性通过各自的订单访问它们

查询是什么样子的:

要使用订单类型获取订单,请执行以下操作:

var order = context.Orders.Include(x => x.OrderType).Where(x => x.OrderId == orderId).Single();
这是一个使用
Include
的即时加载场景。它将检索单个订单,并填充其OrderType。从中可以使用order.OrderType.name获取订单类型名称。即时加载是可选的。只要OrderType导航声明为虚拟,并且DbContext上未禁用延迟加载,EF就可以根据需要加载延迟加载属性。OrderType不会与上述表达式中的订单一起获取,但是访问订单上的
.OrderType
属性将发出信号EF运行另一个查询来获取并填充该订单的订单类型。这仅在加载订单的DbContext尚未公开时有效。如果严重依赖延迟加载,则会导致性能问题

为了获得更好的性能,您可以使用投影
。选择
填充视图模型/dto,而不是依赖于整个实体。如果我们要使用订单类型名称执行搜索,列出订单,我们可以声明OrderSummaryViewModel,如下所示:

// Something like your OrderJoinTable?
[Serializable]
public class OrderSummaryViewModel
{
   public int OrderId { get; set; }
   public string OrderNumber { get; set; }
   public string OrderType { get; set; }
}
然后在提取这些记录时:

var orders = context.Orders.Select( x => new OrderSummaryViewModel
{
    OrderId = x.OrderId,
    OrderNumber = x.OrderNumber,
    OrderType = x.OrderType.Name
}).ToList();
注意,这不需要求助于即时加载,并且填充视图模型,因此我们也不需要担心延迟加载。我们可以访问Linq表达式中的导航属性,以便根据需要进行筛选并填充显示模型,而无需担心显式连接

显式连接将保留在需要将完全无关的实体彼此链接的情况下,例如一个实体与几个可能的实体之一有关系的情况。例如,如果我有一个地址表,它有一个EntityId键,可以分别包含Customer或Business表中的CustomerId或BusinessId。然而,这种表结构效率很低,通常只有当人们确信它“节省空间”或其他一些优化时才存在。它将遇到没有FK关联的性能问题,并且在没有适当约束的情况下容易“中断”。尽管如此,在处理类似这样的遗留系统时,您仍然可以利用实体之间的显式连接


EF可以映射多对一引用(如上所述)1对多子集合(如订单到订单行)1对1关系(订单到订单交付详细信息)和多对多关系(例如客户到地址,其中一个客户可以有多个地址,一个地址可以链接到多个客户,所有这些都使用CustomerAddress表(CustomerId+AddressId))您可以找到关于如何使用EF映射这些场景的示例。

当我在Access中有表时,我使用其查询连接两个表,然后我可以从该查询创建数据视图,并在需要时更改其记录和数据。根据您的解释,您说最好的方法是映射关系。之后,我应该创建j使用LINQ语法和EF会使用关系吗?在这个方法中,还有一件事让我感到困惑,那就是如何定义新生成的联接表,并在我的模型中没有它的时候将其作为IQueryable使用。为什么它不是我的一部分呢
var orders = context.Orders.Select( x => new OrderSummaryViewModel
{
    OrderId = x.OrderId,
    OrderNumber = x.OrderNumber,
    OrderType = x.OrderType.Name
}).ToList();