EntityFramework,不存在则插入,否则更新
我有一个实体集国家,反映了我的数据库中的数据库表 '<'char(2),char(3),nvarchar(50>。
我有一个解析器,它返回已解析国家/地区的 Country[] 数组,并且在以正确的方式更新它时遇到问题是:获取国家/地区数组,对于那些尚未在数据库中的国家/地区插入它们,以及那些现有的更新(如果有任何字段不同)。 事情
void Method(object sender, DocumentLoadedEvent e)
{
var data = e.ParsedData as Country[];
using(var db = new DataContractEntities)
{
//Code missing
}
}
我在想类似的
for(var c in data.Except(db.Countries)) but it wount work as it compares on wronge fields.
希望有人以前遇到过这个问题,并为我提供一个解决方案,如果我不能使用 Country 对象并轻松插入/更新它们的数组,我认为使用该框架没有多大好处,因为我认为它更快。编写一个自定义 sql 脚本来插入它们,而不是在插入之前检查一个国家/地区是否已在数据库中?
解决方案
请参阅帖子的答案,
我将 override equals 添加到我的国家/地区类:
public partial class Country
{
public override bool Equals(object obj)
{
if (obj is Country)
{
var country = obj as Country;
return this.CountryTreeLetter.Equals(country.CountryTreeLetter);
}
return false;
}
public override int GetHashCode()
{
int hash = 13;
hash = hash * 7 + (int)CountryTreeLetter[0];
hash = hash * 7 + (int)CountryTreeLetter[1];
hash = hash * 7 + (int)CountryTreeLetter[2];
return hash;
}
}
然后执行以下操作:
var data = e.ParsedData as Country[];
using (var db = new entities())
{
foreach (var item in data.Except(db.Countries))
{
db.AddToCountries(item);
}
db.SaveChanges();
}
I'm having a Entity-Set Countries, reflecting a database table '<'char(2),char(3),nvarchar(50> in my database.
Im having a parser that returns a Country[] array of parsed countries, and is having issues with getting it updated in the right way. What i want is: Take the array of countries, for those countries not already in the database insert them, and those existing update if any fields is different. How can this be done?
void Method(object sender, DocumentLoadedEvent e)
{
var data = e.ParsedData as Country[];
using(var db = new DataContractEntities)
{
//Code missing
}
}
I was thinking something like
for(var c in data.Except(db.Countries)) but it wount work as it compares on wronge fields.
Hope anyone have had this issues before, and have a solution for me. If i cant use the Country object and insert/update an array of them easy, i dont see much benefict of using the framework, as from performers i think its faster to write a custom sql script that inserts them instead of ect checking if an country is already in the database before inserting?
Solution
See answer of post instead.
I added override equals to my country class:
public partial class Country
{
public override bool Equals(object obj)
{
if (obj is Country)
{
var country = obj as Country;
return this.CountryTreeLetter.Equals(country.CountryTreeLetter);
}
return false;
}
public override int GetHashCode()
{
int hash = 13;
hash = hash * 7 + (int)CountryTreeLetter[0];
hash = hash * 7 + (int)CountryTreeLetter[1];
hash = hash * 7 + (int)CountryTreeLetter[2];
return hash;
}
}
and then did:
var data = e.ParsedData as Country[];
using (var db = new entities())
{
foreach (var item in data.Except(db.Countries))
{
db.AddToCountries(item);
}
db.SaveChanges();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我会直接做:
我不知道你的应用程序必须运行这个的频率或你的世界有多少个国家。但我感觉这并不是你必须考虑复杂的性能优化的地方。
编辑
另一种方法仅发出一个查询:
I would do it straightforward:
I don't know how often your application must run this or how many countries your world has. But I have the feeling that this is nothing where you must think about sophisticated performance optimizations.
Edit
Alternative approach which would issue only one query:
使用更高版本的 EF 的现代形式是:
AlreadyExists
可以通过检查密钥或查询数据库来查看该项目是否已存在。The modern form, using later EF versions would be:
AlreadyExists
can come from checking the key or by querying the database to see whether the item already exists there.您可以实现自己的
IEqualityComparer
并将其传递给Except()
方法。假设您的 Country 对象具有Id
和Name
属性,该实现的一个示例可能如下所示:并将其用作
虽然,在您的情况下,您似乎只需要提取新对象,如果您的 Id 是 Guid,则可以使用 var newCountries = data.Where(c => c.Id == Guid.Empty); 。
最好的方法是检查
Country.EntityState
属性,并根据值(分离、修改、添加等)采取操作。您需要提供有关您的
数据<的更多信息/code> 集合包含即通过实体框架从数据库检索的 Country 对象,在这种情况下可以跟踪它们的上下文,或者您是否使用其他方式生成它们。
You can implement your own
IEqualityComparer<Country>
and pass that to theExcept()
method. Assuming your Country object hasId
andName
properties, one example of that implementation could look like this:and use it as
Although, in your case it looks like you just need to extract new objects, you can use
var newCountries = data.Where(c => c.Id == Guid.Empty);
if your Id is Guid.The best way is to inspect the
Country.EntityState
property and take actions from there regarding on value (Detached, Modified, Added, etc.)You need to provide more information on what your
data
collection contains i.e. are the Country objects retrieved from a database through the entityframework, in which case their context can be tracked, or are you generating them using some other way.我不确定这将是最好的解决方案,但我认为您必须从数据库获取所有国家/地区,然后使用解析的数据进行检查
I am not sure this will be the best solution but I think you have to get all countries from DB then check it with your parsed data