问题描述
|
我正在使用EF 4.1 Code First,并且正在制作一个可配置的实用程序来解析/导入大的分隔文件。文件中的每一行可能包含几个实体的数据。
文件的确切数据和布局在构建时将是未知的(每个客户端的配置都不同),因此我将其配置为可配置的。
示例模型(简体)
public class Contact {
public int Id { get; set;}
public string Name { get; set; }
}
public class Account {
public int Id { get; set; }
public decimal Balance { get; set; }
public bool IsOpen { get; set; }
}
根据客户端的不同,文件可能包含联系方式和/或客户信息。由于这些文件的大小(大量记录),我们必须使用sqlBulkcopy进行数据加载。在编译时还不清楚究竟将对数据运行哪些规则(客户端验证更改等)。
我想要一个表和类,例如ImportRecord,来保存导入的数据。我当前的工人阶级是:
public class ImportRecord {
public string Contact_Name { get; set; }
public decimal Account_Balance { get; set; }
public bool Account_IsOpen { get; set; }
}
这里的问题是,当我们在模型类中添加/更改字段时,ImportRecord也必须更改-它是重复的/不理想的。对我来说,导入数据驻留在单个表中对于简化sqlBulkcopy导入有点重要。
我理想的ImportRecord类如下所示:
public class ImportRecord {
public Contact Contact { get; set; }
public Account Account { get; set; }
}
但这只会创建一个带有两个外键的表(除了抱怨没有FK属性)。有没有办法让实体类的行为更像是ImportRecord的非规范化,无键,复杂类型?我要彻底解决这个问题吗?
谢谢!
解决方法
实体不能嵌套,同时复杂类型不能具有实体密钥,因此您不能使用一个代替其他实体,但是可以尝试这种小作弊。我刚刚测试了它至少可以创建正确的数据库结构:
public class Context : DbContext
{
public DbSet<Account> Accounts { get; set; }
public DbSet<Contact> Contacts { get; set; }
public DbSet<ImportRecord> ImportRecords { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ComplexType<ContactBase>();
modelBuilder.ComplexType<AccountBase>();
}
}
public class ContactBase
{
public string Name { get; set; }
}
public class AccountBase
{
public decimal Balance { get; set; }
public bool IsOpen { get; set; }
}
public class Contact : ContactBase
{
public int Id { get; set; }
}
public class Account : AccountBase
{
public int Id { get; set; }
}
public class ImportRecord
{
public int Id { get; set; }
public ContactBase Contact { get; set; }
public AccountBase Account { get; set; }
}