我们正在审查通用存储库模式中的两种不同方法。 当前,想要将主键映射到ID。这样做的目的是映射到利用Id的通用存储库接口。下面提供了两种解决方案。
.FindPrimaryKey()。Properties对性能的影响是什么。尝试查找主键时是否会导致数据库表上的模式锁定?它会导致应用程序运行缓慢吗?
与部分类方法解决方案2相比,它的性能如何? 哪种方法在性能上更好?
注意:架构师要求在工作场所使用存储库模式,因此请实施它。知道围绕这个问题有争论,但没有我的电话。
脚手架模型示例:
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()
Generic Repository in C# Using Entity Framework
使用EF FindPrimaryKey()
var idName = _context.Model.FindEntityType(typeof(TEntity))
.FindPrimaryKey().Properties.Single().Name;
解决方案2:局部类映射
Net Core: Create Generic Repository Interface Id Mapping for All Tables Auto Code Generation
public partial class Property: IEntity
{
[NotMapped]
public int Id { get => PropertyId; set => PropertyId = value; }
}
答案 0 :(得分:4)
关于第一种方法(使用EF Core元数据服务):
首先,EF Core是ORM(对象关系映射器),其中最重要的是 Mapper 。
第二,它使用所谓的基于代码的模型,这意味着所有映射均由代码而非实际数据库提供(即使该模型是通过对现有数据库进行反向工程创建的)
简单来说,EF Core在运行时创建一个内存数据结构,其中包含有关类和属性的信息(元数据),以及它们到数据库表,列和关系的映射。所有这些信息都基于纯代码模型-实体类,约定,数据注释和流畅的配置。
所有EF Core运行时行为均基于该元数据模型。 EF Core在构建查询,将查询结果映射到对象,链接导航属性,生成创建/更新/删除命令及其执行顺序,在获取真正的自动生成的主键值之后更新临时FK属性值时在内部使用它。>
因此,元数据模型和发现服务(方法)使用优化的数据结构,并且(必须)非常有效。同样,不涉及数据库操作。
因此第一种方法非常有效。与实际查询的建立,执行和实现相比,通过元数据服务获得PK 属性名称对性能的影响可以忽略不计。
第一种方法的性能也类似于您在另一种方法中使用的EF Core Find
方法。请注意,在调用Find
方法时,您只需传递PK值而不是属性。因此,方法实现应该以某种方式知道如何构建Where
表达式,对吗?并且其内部功能与建议的代码段非常相似。
关于第二种方法:
这根本不具有可比性,因为它不起作用。可以使用基类/接口,但前提是必须映射实际的属性名-就像所有类都具有Id
属性一样,并且可以使用{将其映射到数据库表中的其他列名 {1}}数据注释或[Column]
流利的API。
在您的示例中,HasColumnName
属性为Id
(忽略)。这意味着EF Core无法映射到表列。您通过代码(属性获取器/设置器)将其映射到另一个属性的事实并不重要。 EF Core是不是的(反)编译器,它看不到您的代码,因此无法将使用此类属性的LINQ查询转换为SQL。
在EF Core 2.x中,哪个导致client evaluation(效率很低,读取整个表并在内存中应用过滤器),或者导致客户端评估为configured to do so的异常。而在EF Core 3.0+ it will always be an exception中。
因此,如果您不删除[NotMapped]
和 map 这样的属性PropertyId
(对于“数据库优先”的模型来说很难),第二个“方法”。并且即使您可以映射实际的Id
属性,您节省的时间也只有几毫秒。再说一次,当使用Id
时,您不必担心性能,为什么还要麻烦使用相同(或相似)方法的方法。