网络核心:实体框架中的通用存储库主ID密钥性能 [英] Net Core: Generic Repository Primary Id Key Performance in Entity Framework

查看:120
本文介绍了网络核心:实体框架中的通用存储库主ID密钥性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在审查通用存储库模式中的两种不同方法。
当前,要将主键映射到ID。这样做的目的是映射到利用Id的通用存储库接口。下面提供了两个解决方案。

We are reviewing two different methods in generic repository patterns. Currently, want to map primary keys to Ids. The purpose of this is to map to the Generic Repository Interface which utilizes Id. Two solutions are provided below.

.FindPrimaryKey()。Properties的性能含义是什么?尝试查找主键时是否会导致数据库表上的模式锁定?它会导致应用程序运行缓慢吗?

What are performance implications of .FindPrimaryKey().Properties. Does it cause a schema lock on database table in trying to find the primary key? Does it cause any application slowness?

与部分类方法解决方案2相比,它的性能如何?
什么是更好的性能选择?

How does it compare in performance vs Partial Class Method Solution 2? What option is better performance-wise?

注意:架构师要求在工作场所使用存储库模式,因此应予以实施。知道围绕这个问题有争论,但不是我的电话。

Note: Architects demand the use of repository pattern at the workplace, so implementing it. Know there is debate surrounding this issue, but not my call.

脚手架模型示例:

namespace Datatest
{
    public partial class Property
    {
        public int Property { get; set; }
        public int DocumentId { get; set; }
        public string Address { get; set; }
    }
}

所有表的样本通用基本存储库:

    public T Get(int id)
    {
        return Table.Find(id);
    }
    public async Task<T> GetAsync(int id)
    {
        return await Table.FindAsync(id);
    }
    public T Single(Expression<Func<T, bool>> predicate)
    {
        return All.Single(predicate);
    }
    public async Task<T> SingleAsync(Expression<Func<T, bool>> predicate)
    {
        return await All.SingleAsync(predicate);
    }
    public T FirstOrDefault(int id)
    {
        return All.FirstOrDefault(CreateEqualityExpressionForId(id));
    }

解决方案1:FindPrimaryKey()

C#中使用实体框架的通用存储库

使用EF FindPrimaryKey()

use EF FindPrimaryKey()

var idName = _context.Model.FindEntityType(typeof(TEntity))
        .FindPrimaryKey().Properties.Single().Name;

解决方案2:局部类映射

网络核心:为所有表创建通用存储库接口ID映射自动生成代码

public partial class Property: IEntity
{
    [NotMapped]
    public int Id { get => PropertyId; set => PropertyId = value; }
}


推荐答案

关于第一种方法(使用EF Core元数据服务):

Regarding the first approach (using EF Core metadata services):

首先,EF Core是ORM(对象关系映射器),其中最重要的是 Mapper

First, EF Core is ORM (Object Relational Mapper), with most important here is Mapper.

其次,它使用所谓的基于基于代码的模型,这意味着所有映射均由代码而非实际数据库提供(即使

Second, it uses the so called code based model, which means all the mappings are provided by code and not the actual database (even though the model is created by reverse engineering of an existing database).

简单来说,EF Core在运行时创建一个内存数据结构,其中包含有关类和对象的信息(元数据)。属性及其到数据库表,列和关系的映射。所有这些信息都基于纯代码模型-实体类,约定,数据注释和流畅的配置。

In simple words, EF Core creates at runtime a memory data structure containing the information (metadata) about classes and properties, and their mappings to database tables, columns and relationships. All that information is based on pure code model - the entity classes, conventions, data annotations and fluent configuration.

所有EF Core运行时行为均基于该元数据模型。 EF Core在构建查询,将查询结果映射到对象,链接导航属性,生成创建/更新/删除命令及其执行顺序,在获取真正的自动生成的主键值之后更新临时FK属性值时在内部使用它。

All EF Core runtime behaviors are based on that metadata model. EF Core uses it internally when building queries, mapping the query results to objects, linking navigation properties, generating create/update/delete commands and their order of execution, updating temporary FK property values after getting the real autogenerated principal key values etc.

因此,元数据模型和发现服务(方法)使用优化的数据结构,并且(必须)非常有效。同样,不涉及数据库操作。

Hence the metadata model and discovering services (methods) use optimized data structures and are (has to be) quite efficient. And again, no database operations are involved.

因此,第一种方法非常有效。与实际查询的建立,执行和实现相比,通过元数据服务获得PK 属性名称的性能影响可忽略不计。

So the first approach is quite efficient. The performance impact of obtaining the PK property name via metadata service is negligible compared to actual query building, execution and materialization.

第一种方法类似于您在另一种方法中使用的EF Core Find 方法。请注意,在调用 Find 方法时,您只是传递PK值而不是属性。因此,方法实现应该以某种方式知道如何构建 Where 表达式,对吗?并且它的内部操作与建议的代码段非常相似。

Also the performance of the first approach is similar to EF Core Find method which you are using in another method. Note that when calling Find method you just pass the PK value(s) and not the properties. So the method implementation should somehow know how to build the Where expression, right? And what it does internally is very similar to the suggested snippet.

关于第二种方法:

这根本不具有可比性,因为它不起作用。可以使用基类/接口,但是仅当映射了实际的属性名称时-就像所有类都具有 Id 属性一样,并且已将其映射到其他列名称,使用 [Column] 数据注释或 HasColumnName 流利的API。

It's simply not comparable because it doesn't work. It's possible to use base class/interface, but only if the actual property name is mapped - like all classes have Id property, and it's mapped to different column name in the database tables using [Column] data annotation or HasColumnName fluent API.

在您的示例中, Id 属性为 [NotMapped] (忽略)。这意味着EF Core无法映射到表列。您通过代码(属性获取器/设置器)将其映射到另一个属性这一事实并不重要。 EF Core不是(em)编译器,它看不到您的代码,因此无法将使用此类属性的LINQ查询转换为SQL。

In your example, the Id property is [NotMapped] (ignored). Which means EF Core cannot map to the table column. The fact that your are mapping it to another property via code (property getter/setter) doesn't matter. EF Core is not a (de)compiler, it can't see your code, hence cannot translate a LINQ query using such properties to SQL.

其中哪个版本在EF Core 2.x中导致客户端评估(效率很低,读取整个表并在内存中应用过滤器),或者如果客户端评估为已配置为此。并且在EF Core 3.0+中它总是一个例外

Which in EF Core 2.x leads to either client evaluation (very inefficient, reading to whole table and applying the filter in memory), or exception if client evaluation is configured to do so. And in EF Core 3.0+ it will always be an exception.

因此,如果您不要删除 PropertyId map 这样的属性 Id (这很难对于数据库优先模型),则应避免第二个方法。而且,即使您可以映射实际的 Id 属性,您节省的时间也只有几毫秒。再说一次,当使用 Find 时,您不必担心性能,为什么还要麻烦使用相同(或相似)方法的方法。

So in case you don't remove properties like PropertyId and map the property Id (which would be hard with "database first" models), the second "approach" should be avoided. And even if you can map the actual Id property, all you'll save would be a few milliseconds. And again, when using Find you don't bother about performance, why bother with methods that uses the same (or similar) approach.

这篇关于网络核心:实体框架中的通用存储库主ID密钥性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆