需要帮助了解实体框架

Posted

技术标签:

【中文标题】需要帮助了解实体框架【英文标题】:Need help understanding Entity Framework 【发布时间】:2021-11-16 07:19:57 【问题描述】:

我的前任为 HR 编写了一个 Web 应用程序,用于从我们的 HRMS 中提取关于 401k 贡献的数据。事实证明,他的报告仅在准确的美元金额而不是百分比时才提取追赶捐款。他使用实体框架来做到这一点。我是脚本编写者,而不是程序员。我知道阿多。我不知道实体框架。

数据库有一个名为EARNED 的列。 Catch Up Contribution Amounts 获得代码 D03。 Catch Up Contribution Percentage 获得代码 D03B。此列还有其他几个可能的值:D04、D31、E40 等。不知何故,他的报告只提取了 D03 行。它还需要拉取 D03B 行。

如果我正在编写 SQL,它会是这样的

SELECT * 
FROM [SageHRMS_900].[dbo].[UPCHKD] 
WHERE [EARNDED] = 'D03B' 
   OR [EARNDED] = 'D03'

显然 Entity Framework 没有使用类似的东西。相反,我看到的只是这样的东西

hrmsEntity hrms = new hrmsEntity(dbConnection);
var detail = hrms.TRP_ConDetail.ToList();

foreach (var line in hrms.TRP_ConDetail.ToList())

    fileData += line.Plan + line.RecordID + line.Date + line.SSN + line.Fund + line.LoanNum +
    line.Amount + line.Salary + line.SalaryType + line.ContType + line.StateTax + 
    line.LoanPayType + line.Filler01 + Environment.NewLine;

我看到了 TRP_Con 类的定义位置

public class TRP_ConDetail

    [Key]
    public Guid ID  get; set; 
    public string Plan  get; set; 
    public string RecordID  get; set; 
    public string Date  get; set; 
    public string Name  get; set; 
    public string SSN  get; set; 
    public string Fund  get; set; 
    public string Desc  get; set; 
    public string LoanNum  get; set; 
    public string Amount  get; set; 
    public decimal Dollars  get; set; 
    public string Salary  get; set; 
    public string SalaryType  get; set; 
    public string ContType  get; set; 
    public string StateTax  get; set; 
    public string LoanPayType  get; set; 
    public string Filler01  get; set; 
    public int? LineSq  get; set; 

我没有看到代码如何知道将选择限制为仅 D03 类型的贡献。


编辑: 添加 hrmsEntity 类

public partial class hrmsEntity : DbContext

    //public hrmsEntity()
    //    : base("name=hrmsEntityModelDSM")
    //
    //
    /*Base entity connection depends on the entity of the company*/
    public hrmsEntity(string dbConnection) : base($"name=dbConnection")  

    //public hrmsEntity(string connectionString) : base(connectionString)  

    public virtual DbSet<TRP_ConSourceTotal> TRP_ConSourceTotal  get; set; 
    public virtual DbSet<TRP_ConDetail> TRP_ConDetail  get; set; 
    public virtual DbSet<TRP_MaintFile> TRP_MaintFile  get; set; 

UPCHKD 是 900 数据库中的一个表。

@Dai 评论:“另外,请(为了每个人的理智)请使用您的 IDE 的 Refactor Rename 功能将 hrmsEntity 重命名为 HrmsDbContext” 是的...我不是程序员。 :) 我编写 VBA 或 PowerShell 脚本。调整 C# 几乎是我能力的极限。

【问题讨论】:

hrmsEtntiy.TRP_ConDetail 看起来像 DbSet&lt;T&gt;,对吗? 正确:public virtual DbSet&lt;TRP_ConDetail&gt; TRP_ConDetail get; set; 在您的 SQL 查询中使用UPCHKD,是VIEW 还是TABLE?它与TRP_ConDetail 相比如何?有hrmsEntityUPDCHKD 成员吗? 另外,请please please(为了大家的理智)please使用你的IDE重构重命名功能,将hrmsEntity 重命名为HrmsDbContext 您无需重新编写任何内容。如果他确实使用了 ef / ef core,那么使用 linq 真的会节省你很多时间。这很容易学习。它的语法有两种形式:一种模仿 SQL,另一种对编码器更友好。 【参考方案1】:

第一步是查看此 TRP_ConDetail 映射到的位置/内容,因为该名称中的任何内容都与 UPCHKD 表无关。由于实体类中除了[Key] 之外没有其他属性,因此要检查的两个地方将是在DbContext 本身(hrmsEntity)中的OnModelCreating() 方法,或者在EntityTypeConfiguration&lt;TRP_ConDetail&gt; 类型的解决方案中寻找一个类将指示该实体映射到数据库中的哪个表或视图。这也将显示任何指向已为该类重命名的“Earned”列的属性。

鉴于您提到他的代码仅提取“D03”值,我的直觉是 TRP_ConDetail 是一个视图,因为您粘贴的代码中没有过滤代码逻辑。该代码将实体映射到表或视图并输出整个集合。数据库中可能有一个名为 TRP_ConDetail 的视图,您可以在其中找到类似 WHERE UPCHKD.EARNED = 'D03' 的内容,您可以将其扩展为包含“D03B”值。

但是,请记住,如果系统是这样实现的,这是一个警告,这将是一个非常糟糕的设计,因为如果您进行更改它将影响 任何地方,此 TRP_ConDetail @ 987654325@ 被引用。任何其他只需要 D03 的代码现在将同时接收 D03 和 D03B,因此这很可能会在系统的其他区域引入错误。应避免在底层视图中过滤规则,除非正是出于这个原因,它是非常核心级别的全局应用规则。通常您希望看到的是在 Linq 表达式中完成的过滤:

例如,如果视图简单地将这个 UPCHKD 和一些相关数据组合在一起,其中像“Earned”这样的字段是视图的一部分,那么该代码区域中的 Linq 查询看起来更像:

var detail = hrms.TRP_ConDetail
    .Where(x => x.Earned == "D03")
    .ToList();

更新到以下内容既安全又容易:

var detail = hrms.TRP_ConDetail
    .Where(x => x.Earned == "D03" || x.Earned == "D03B")
    .ToList();

不幸的是,它看起来不像是这样实现的,看看为什么不这样做会很有趣,以及 EF 是否真的被用来代替 ADO.Net。

您应该与您的雇主讨论请一位熟悉 Entity Framework 的开发人员来仔细查看实施,以确认是否使用了视图并确定可能更新基础视图或“修复”它的任何风险,以便选择标准由 EF 完成,而不是在视图定义中。 (在引用该视图的任何地方都会产生审查、修改和测试的效果)

【讨论】:

啊!我没有想到要寻找视图。成功了!

以上是关于需要帮助了解实体框架的主要内容,如果未能解决你的问题,请参考以下文章

请帮助我了解 GAE 数据存储区中的实体层次结构

“将 Tiny 视为布尔值”和实体框架 4

如何在设计数据库模型中添加实体框架地理位置属性

实体框架 6:在上下文中禁用跟踪时更新实体

无法生成显式迁移 - 具有多个上下文/配置的实体框架 6.1.3

实体框架 4 还是 DataSet?