Нужна помощь в понимании структуры сущностей

#c# #entity-framework #entity-framework-6

Вопрос:

Мой предшественник написал веб-приложение для отдела кадров, чтобы получать данные из наших УЧР о взносах в размере 401k. Оказывается, что в его отчете приводятся данные о взносах только в том случае, если они составляют точную сумму в долларах, а не в процентах. Для этого он использовал Entity Framework. Я сценарист, а не программист. Я знаю АДО. Я не знаю Entity Framework.

В базе данных есть столбец с именем EARNED . Догоняющие суммы взносов получают код D03. Догоняющий процент вклада получает код 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: «Кроме того, пожалуйста, пожалуйста, пожалуйста (для здравомыслия всех), пожалуйста, используйте функцию переименования рефакторинга вашей среды разработки, чтобы переименовать hrmsEntity в HrmsDbContext» Да… Я не программист. 🙂 Я пишу сценарии VBA или PowerShell. Настройка C# — это в значительной степени предел моих возможностей.

Комментарии:

1. hrmsEtntiy.TRP_ConDetail похоже на а DbSet<T> , это верно?

2. Правильный: public virtual DbSet<TRP_ConDetail> TRP_ConDetail { get; set; }

3. В вашем SQL-запросе , который вы используете UPCHKD , это a VIEW или a TABLE ? Как это соотносится с TRP_ConDetail ? Есть ли UPDCHKD кто-нибудь из членов hrmsEntity ?

4.Кроме того, пожалуйста, пожалуйста , пожалуйста (для всеобщего здравомыслия), пожалуйста, используйте функцию переименования рефакторинга вашей среды разработки для переименования hrmsEntity HrmsDbContext .

5. Вам не нужно ничего переписывать. Если он действительно использовал ядро ef / ef, использование linq действительно сэкономит вам много времени. Этому очень легко научиться. Его синтаксис имеет два варианта: один, который имитирует SQL, а другой более удобен для кодировщика.

Ответ №1:

Первым шагом было бы посмотреть, где/с чем сопоставлен этот TRP_ConDetail, потому что ничто в этом имени не коррелирует с таблицей UPCHKD. Поскольку в классе сущностей нет других атрибутов , кроме [Key] , два места для проверки будут находиться в самом DbContext (hrmsEntity) для OnModelCreating() метода или в поиске класса в решении типа EntityTypeConfiguration<TRP_ConDetail> , который указывал бы, с какой таблицей или представлением в базе данных сопоставлена эта сущность. Это также выявит любые свойства, указывающие на столбец «Заработано», которые были переименованы для класса.

Учитывая, что вы упомянули, что его код извлекает только значения «D03», я предполагаю, что TRP_ConDetail-это представление, потому что в этом вставленном коде нет логики кода фильтрации. Этот код сопоставляет сущность либо с таблицей, либо с представлением и выводит весь набор. В базе данных может быть представление под названием TRP_ConDetail, в котором вы найдете что-то подобное WHERE UPCHKD.EARNED = 'D03' , которое вы расширили бы, включив значение «D03B».

ОДНАКО имейте в виду, что если система была реализована именно так, это предупреждение о том, что это будет очень плохой дизайн, поскольку, если вы внесете это изменение, оно повлияет на все, на что DbSet ссылается этот TRP_ConDetail. Любой другой код, который ожидал только D03, теперь получит как D03, так и D03B, так что это вполне может привести к ошибкам в других областях системы. Следует избегать правил фильтрации в базовых представлениях, если только они не являются глобально применяемыми правилами на уровне ядра именно по этой причине. Обычно то, что вы ожидаете увидеть, — это фильтрация, выполняемая в выражении Linq:

Например, если бы представление просто объединило этот UPCHKD и, возможно, некоторые связанные данные, в которых поле типа «Заработал» было частью представления, то запрос 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, а не в определении представления. (что будет иметь побочные эффекты для просмотра, пересмотра и тестирования везде, где упоминается это представление)

Комментарии:

1. Боже! Мне и в голову не пришло искать Вид из окна. Вот и все!