保存前如何检查重复项?

时间:2012-12-05 22:21:31

标签: 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
    public DateTime Creation { get; set; }
}

public class ListingData
{
   public int listing_id; // PK

   ....
}

我正从另一个来源检索'ThingWithLIstings'并将其写入我的数据库。棘手的部分是任何数量的列表都可以向同一个ListingData报告。因此,当我添加或更新ThingWithListings时,我需要查看ListingData是否已经存在,如果存在,只需使用那个。

我是EF的新手,所以我一直在使用作者维克斯文章here中的AddOrUpdate:显然,这对于这种情况不起作用,所以我已经尝试了一天左右找出正确的方法来做到这一点。我会告诉你我主要失败尝试的所有故事,希望有人能告诉我正确的方法。

3 个答案:

答案 0 :(得分:0)

if (DatabaseContext.ListingData.Any(l => l.listing_id == myId)) 
{   
  //already exists 
}
else 
{   
  //do whatever 
}

答案 1 :(得分:0)

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();
    }
}

答案 2 :(得分:0)

我假设除Data对象引用外,您的Listing类中还有原始外键字段listing_id。如果没有,我建议添加它。

您可以从列表或数组中获取现有listing_id开始。这样可以节省大量数据库往返次数。

然后该过程非常简单:对于到达的每个Listing对象,检查其listing_id是否出现在预先获取的列表中:

  • 如果是,请对ListingData执行任何操作 - 只需添加(或更新)Listing,包括listing_id属性。
  • 如果没有,请添加Listing并将Listing.DataListingData对象设置为新(已添加)对象。 EF将设置密钥。

(请注意,这假设没有并发用户修改ListingData,因此可以安全地拍摄Id的快照)