C# 从文本文件进行.NET核心数据库种子设定
我正在尝试为名为Contacts的SQL数据库(localhost server)表添加种子,其中包含大约200000条联系人记录,以测试我在C#中的搜索效率。我正在使用.NETCore2.2,并通过代码优先的方法对数据库进行种子设定。为了得到200000条记录,我有一个包含450个名字的文本文件和另一个包含450个姓氏的文本文件。然后,我使用StreamReader(下面的代码)在这两个文件中循环创建联系人对象C# 从文本文件进行.NET核心数据库种子设定,c#,visual-studio-2017,ef-code-first,ef-fluent-api,.net-core-2.2,C#,Visual Studio 2017,Ef Code First,Ef Fluent Api,.net Core 2.2,我正在尝试为名为Contacts的SQL数据库(localhost server)表添加种子,其中包含大约200000条联系人记录,以测试我在C#中的搜索效率。我正在使用.NETCore2.2,并通过代码优先的方法对数据库进行种子设定。为了得到200000条记录,我有一个包含450个名字的文本文件和另一个包含450个姓氏的文本文件。然后,我使用StreamReader(下面的代码)在这两个文件中循环创建联系人对象 // Model public class Contact { publi
// Model
public class Contact
{
public int Id {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
}
public void Configure(EntityTypeBuilder<Contact> builder, int recordCounter)
{
builder.ToTable("Contacts");
builder.HasKey(t => t.Id);
builder.Property(t => t.Id).ValueGeneratedOnAdd().IsRequired();
builder.Property(t => t.FirstName).IsRequired();
builder.Property(t => t.LastName).IsRequired();
using (StreamReader sr = new StreamReader(@".\FirstName.txt"))
{
string firstName;
// Read and display lines from the file until the end of
// the file is reached.
while ((firstName = sr.ReadLine()) != null)
{
using (StreamReader sr2 = new StreamReader(@".\LastName.txt"))
{
string lastName;
// Read and display lines from the file until the end of
// the file is reached.
while ((lastName = sr2.ReadLine()) != null)
{
// negative value Id to avoid collision with non-seed data
builder.HasData(new Contact
{
Id = -(recordCounter),
FirstName = firstName,
LastName = lastName
}
);
recordCounter++;
}
}
}
}
}}
//模型
公共类联系人
{
公共int Id{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
}
公共void配置(EntityTypeBuilder,int recordCounter)
{
建造商。可转让(“合同”);
HasKey(t=>t.Id);
builder.Property(t=>t.Id).ValueGeneratedOnAdd().IsRequired();
属性(t=>t.FirstName).IsRequired();
属性(t=>t.LastName).IsRequired();
使用(StreamReader sr=newstreamreader(@“\FirstName.txt”))
{
字符串名;
//读取并显示文件中的行,直到
//已到达该文件。
而((firstName=sr.ReadLine())!=null)
{
使用(StreamReader sr2=newstreamreader(@“\LastName.txt”))
{
字符串lastName;
//读取并显示文件中的行,直到
//已到达该文件。
而((lastName=sr2.ReadLine())!=null)
{
//负值Id以避免与非种子数据冲突
builder.HasData(新联系人
{
Id=-(记录计数器),
FirstName=FirstName,
LastName=LastName
}
);
记录计数器++;
}
}
}
}
}}
我正在捕获联系人记录的数量,并使用它来迭代另外两个名为StreetName.txt和CityState.txt的文件,为每个联系人记录创建一个地址。传入的联系人记录计数在循环中递增,并作为外键分配给Addresses表
我同样为联系人创建电话号码(使用随机数生成器)和电子邮件记录,并将其插入电话和电子邮件表中,其中联系人记录的数量增加,并作为外键传入
下面的屏幕截图显示了我遇到的问题
可能感兴趣的其他要点:
请告诉我代码优先迁移、visual studio内部工作、SQL server本地实例等方面我可能不知道的事情。抛开整体方法不谈,您多次打开和关闭姓氏文件,需要重复磁盘IO。至少,将名称加载到集合中一次,然后在该集合上迭代。你也可以并行处理,我同意pinky的观点。从硬盘获取数据比直接从内存获取数据慢得多。而且,一旦你生成了所有这些名称,你就可以将它们保存到一个文件中,并直接从该文件加载它们。我不知道我是否一定同意磁盘IO减慢了进程。我可以很快地完成代码(不是用18h)。我想知道SQL写过程是否是问题所在,因为它试图确保地址、电子邮件和电话表中联系人FK的数据的引用完整性。。。另外,有人知道为什么在截图的VS2017输出窗口中,代码会停留在“Build started:Project:Contact.API,Configuration:Debug any CPU---”这一行吗?即使你不同意,我认为还是值得一试。此外,EF迁移可能不是为这么多记录播种的最佳方式。我的猜测是,它对每条记录进行一次db调用,再加上跟踪实体和一系列其他内务处理。对于一小部分数据来说,它可能工作得很好,但是200k条记录(加上所有地址/电话记录)就太多了。如果您需要生成如此数量的数据,请尝试使用类似SqlBulkCopy的方法。@pinkfloydx33感谢您提供了我的方法(SqlBulkCopy)的替代方法。从长远来看,我将继续对原始问题进行调查,并考虑您关于在短期内取得进展的建议,以便检查我的“搜索”功能的效率(这是整个练习的起点)。