#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
, это aVIEW
или aTABLE
? Как это соотносится с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. Боже! Мне и в голову не пришло искать Вид из окна. Вот и все!