C# 如何在保存前检查重复项?
我花了很长时间才弄明白如何将这样的实体添加到我的数据库中C# 如何在保存前检查重复项?,c#,entity-framework,duplicates,C#,Entity Framework,Duplicates,我花了很长时间才弄明白如何将这样的实体添加到我的数据库中 public class ThingWithListings { public virtual ICollection<Listing> Listings; } public class Listing { public int Id; public virtual ListingData Data { get; set; } // has a FK to ListingData publi
public class ThingWithListings
{
public virtual ICollection<Listing> Listings;
}
public class Listing
{
public int Id;
public virtual ListingData Data { get; set; } // has a FK to ListingData
public DateTime Creation { get; set; }
}
public class ListingData
{
public int listing_id; // PK
....
}
public class ThingWithListings
{
公共虚拟ICollection列表;
}
公共类列表
{
公共int Id;
公共虚拟ListingData数据{get;set;}//对ListingData具有FK
公共日期时间创建{get;set;}
}
公共类列表数据
{
public int listing_id;//PK
....
}
我正在从另一个源中检索“ThingWithLIstings”,并将其写入数据库。棘手的是,任何数量的列表都可能报告给相同的ListingData。因此,当我添加或更新带有Listings的东西时,我需要查看ListingData是否已经存在,如果已经存在,就使用它
我是EF的新手,所以我一直在使用作者Vickers文章中的AddOrUpdate:显然,这不适用于这种情况,所以我花了一天左右的时间来尝试找到正确的方法。我将向大家讲述我的主要失败尝试,希望有人能告诉我正确的方法。var newArrivals=newthingwithlistings();
if (DatabaseContext.ListingData.Any(l => l.listing_id == myId))
{
//already exists
}
else
{
//do whatever
}
newArrivals.Listings=新列表();
newArrivals.Listings.Add(
新清单()
{
creation=DateTime。现在,
ListingData=新的ListingData()
{
清单1\u id=1
}
});
//具有相同ListingData Listing\u id的另一个列表
newArrivals.Listings.Add(
新清单()
{
creation=DateTime。现在,
ListingData=新的ListingData()
{
清单1\u id=1
}
});
//虚拟id生成器
int计数器=1;
使用(var ctx=newdatabase1entities())
{
//从当前数据库上下文获取ListingData
var dbListingData=ctx.ListingData;
//新来者
foreach(在newArrivals.Listings中列出项目)
{
//获取新到达的ListingData的列表id
int id=item.ListingData.listing\u id;
//从数据库中获取ListingData(如果存在)
var listingDataFromDb=dbListingData.FirstOrDefault(i=>i.listing_id==id);
//如果没有,则创建它并将其添加到数据库中
if(listingDataFromDb==null)
{
listingDataFromDb=新ListingData()
{
//使用新员工的登录id
listing_id=item.ListingData.listing_id
};
ctx.ListingData.Add(listingDataFromDb);
ctx.SaveChanges();
}
//使用listingDataFromDb添加列表,它现在引用db ListingData
添加(新清单()
{
id=计数器+++,
creation=item.creation,
ListingData=listingDataFromDb
});
ctx.SaveChanges();
}
}
我假设除了数据
对象引用之外,您的listing类中还有原始外键字段listing\u id
。如果没有,我建议添加它
您可以从获取列表或数组中现有的列表id
开始。这样可以节省以后的大量数据库往返
然后这个过程非常简单:对于每个到达的列表
对象,检查其列表_id
是否出现在预取列表中:
- 如果是这样,请不要使用
——只需添加(或更新)列表数据
,包括列表
属性列表id
- 如果没有,则添加
,并将列表
与列表数据
对象一起设置为新的(添加的)对象。EF将设置键列表数据
(请注意,这假设没有并发用户修改ListingData,因此拍摄Id的快照是安全的)不幸的是,您很可能需要查询整个表以检查每个值是否存在重复。如果有比这更好的方法,我想听听。因此,来自批量传入数据的
listing_id
s可能已经在ListingData表中,也可能不在其中。是吗?你在列表
中有列表id
(顺便说一句,名称混乱)吗?Alex,是的,列表id可能已经在表中了。我可以检测到该项目已经存在,没有问题。那又怎么样?在添加列表对象之前,我无法将现有的ListingData分配到列表对象。我尝试添加Listing对象,然后将Listing.ListingData标记为未更改。看起来不可能那么难,所以我想我一定错过了简单的部分。以后,请在你的帖子中添加描述,而不仅仅是代码。:)
var newArrivals = new ThingWithListings();
newArrivals.Listings = new List<Listing>();
newArrivals.Listings.Add(
new Listing()
{
creation = DateTime.Now,
ListingData = new ListingData()
{
listing_id = 1
}
});
//another Listing with the same ListingData listing_id
newArrivals.Listings.Add(
new Listing()
{
creation = DateTime.Now,
ListingData = new ListingData()
{
listing_id = 1
}
});
//dummy id generator
int counter = 1;
using (var ctx = new Database1Entities())
{
//get the ListingData from the current db context
var dbListingData = ctx.ListingData;
// the new arrivals
foreach (Listing item in newArrivals.Listings)
{
//get the listing_id of a new arrival's ListingData
int id = item.ListingData.listing_id;
//get the ListingData from the db, if it exists
var listingDataFromDb = dbListingData.FirstOrDefault(i => i.listing_id == id);
//if not, create it and add it to the db
if (listingDataFromDb == null)
{
listingDataFromDb = new ListingData()
{
//use the new arrival's listing_id
listing_id = item.ListingData.listing_id
};
ctx.ListingData.Add(listingDataFromDb);
ctx.SaveChanges();
}
//add the Listing by using the listingDataFromDb, which now references the db ListingData
ctx.Listing.Add(new Listing()
{
id = counter++,
creation = item.creation,
ListingData = listingDataFromDb
});
ctx.SaveChanges();
}
}