文件助手和 Entity Framework
Filehelpers and Entity Framework
我正在使用 Filehelpers 来解析一个非常宽的、固定格式的文件,并希望能够获取生成的对象并使用 EF 将其加载到数据库中。当我尝试将对象加载到数据库中时,以及当我尝试添加一个 Id 时,我遇到了一个丢失的关键错误,我得到了一个 Filehelpers 错误。所以似乎任何一个修复都破坏了另一个。我知道我可以将一个 Filehelpers 对象映射到一个 POCO 对象并加载它,但我正在处理几十个(有时是数百个列)所以我宁愿不必经历那个麻烦。
对于解析固定宽度文件并将结果加载到数据库中的其他建议,我也持开放态度。当然,一种选择是使用 ETL 工具,但我宁愿在代码中这样做。
谢谢!
这是 FileHelpers class:
public class AccountBalanceDetail
{
[FieldHidden]
public int Id; // Added to try and get EF to work
[FieldFixedLength(1)]
public string RecordNuber;
[FieldFixedLength(3)]
public string Branch;
// Additional fields below
}
这是处理文件的方法:
public static bool ProcessFile()
{
var dir = Properties.Settings.Default.DataDirectory;
var engine = new MultiRecordEngine(typeof(AccountBalanceHeader), typeof(AccountBalanceDetail), typeof(AccountBalanceTrailer));
engine.RecordSelector = new RecordTypeSelector(CustomSelector);
var fileName = dir + "\MOCK_ACCTBAL_L1500.txt";
var res = engine.ReadFile(fileName);
foreach (var rec in res)
{
var type = rec.GetType();
if (type.Name == "AccountBalanceHeader") continue;
if (type.Name == "AccountBalanceTrailer") continue;
var data = rec as AccountBalanceDetail; // Throws an error if AccountBalanceDetail.Id has a getter and setter
using (var ctx = new ApplicationDbContext())
{
// Throws an error if there is no valid Id on AccountBalanceDetail
// EntityType 'AccountBalanceDetail' has no key defined. Define the key for this EntityType.
ctx.AccountBalanceDetails.Add(data);
ctx.SaveChanges();
}
//Console.WriteLine(rec.ToString());
}
return true;
}
Entity Framework 需要键为 属性,而不是字段,因此您可以尝试将其声明为:
public int Id {get; set;}
我怀疑 FileHelpers 可能会被自动生成的支持字段混淆,因此您可能需要使用长格式才能使用 [FieldHidden]
属性标记支持字段,即
[FieldHidden]
private int _Id;
public int Id
{
get { return _Id; }
set { _Id = value; }
}
但是,您试图将同一个 class 用于两个不相关的目的,这通常是糟糕的设计。一方面 AccountBalanceDetail
是导入格式的规范。另一方面,您也试图用它来描述实体。相反,您应该创建单独的 classes 并使用 LINQ 函数或类似 AutoMapper 的库在两者之间进行映射。
我正在使用 Filehelpers 来解析一个非常宽的、固定格式的文件,并希望能够获取生成的对象并使用 EF 将其加载到数据库中。当我尝试将对象加载到数据库中时,以及当我尝试添加一个 Id 时,我遇到了一个丢失的关键错误,我得到了一个 Filehelpers 错误。所以似乎任何一个修复都破坏了另一个。我知道我可以将一个 Filehelpers 对象映射到一个 POCO 对象并加载它,但我正在处理几十个(有时是数百个列)所以我宁愿不必经历那个麻烦。
对于解析固定宽度文件并将结果加载到数据库中的其他建议,我也持开放态度。当然,一种选择是使用 ETL 工具,但我宁愿在代码中这样做。
谢谢!
这是 FileHelpers class:
public class AccountBalanceDetail
{
[FieldHidden]
public int Id; // Added to try and get EF to work
[FieldFixedLength(1)]
public string RecordNuber;
[FieldFixedLength(3)]
public string Branch;
// Additional fields below
}
这是处理文件的方法:
public static bool ProcessFile()
{
var dir = Properties.Settings.Default.DataDirectory;
var engine = new MultiRecordEngine(typeof(AccountBalanceHeader), typeof(AccountBalanceDetail), typeof(AccountBalanceTrailer));
engine.RecordSelector = new RecordTypeSelector(CustomSelector);
var fileName = dir + "\MOCK_ACCTBAL_L1500.txt";
var res = engine.ReadFile(fileName);
foreach (var rec in res)
{
var type = rec.GetType();
if (type.Name == "AccountBalanceHeader") continue;
if (type.Name == "AccountBalanceTrailer") continue;
var data = rec as AccountBalanceDetail; // Throws an error if AccountBalanceDetail.Id has a getter and setter
using (var ctx = new ApplicationDbContext())
{
// Throws an error if there is no valid Id on AccountBalanceDetail
// EntityType 'AccountBalanceDetail' has no key defined. Define the key for this EntityType.
ctx.AccountBalanceDetails.Add(data);
ctx.SaveChanges();
}
//Console.WriteLine(rec.ToString());
}
return true;
}
Entity Framework 需要键为 属性,而不是字段,因此您可以尝试将其声明为:
public int Id {get; set;}
我怀疑 FileHelpers 可能会被自动生成的支持字段混淆,因此您可能需要使用长格式才能使用 [FieldHidden]
属性标记支持字段,即
[FieldHidden]
private int _Id;
public int Id
{
get { return _Id; }
set { _Id = value; }
}
但是,您试图将同一个 class 用于两个不相关的目的,这通常是糟糕的设计。一方面 AccountBalanceDetail
是导入格式的规范。另一方面,您也试图用它来描述实体。相反,您应该创建单独的 classes 并使用 LINQ 函数或类似 AutoMapper 的库在两者之间进行映射。