CSharp · Console
// Entity Framework Extensions
// Doc: https://entityframework-extensions.net/where-bulk-not-contains
// @nuget: Newtonsoft.Json
// @nuget: Microsoft.EntityFrameworkCore.SqlServer
// @nuget: Z.EntityFramework.Extensions.EFCore
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
public class Program
{
public static void Main()
{
// Doc: https://entityframework-extensions.net/where-bulk-not-contains
SeedDatabase();
var deserializedCustomers = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Customer>>(GetSerializedCustomers());
FiddleHelper.WriteTable("1 - DeserializedCustomers", deserializedCustomers);
// ## How to use the method WhereBulkNotContains?
// The most basic scenario is passing a list to the `WhereBulkNotContains` method.
// The `WhereBulkNotContains` method will filter entities to exclude those contained in the list.
{
using (var context = new EntityContext())
{
// The `JOIN` statement will use the default entity key if none is provided (CustomerID)
var customers = context.Customers.WhereBulkNotContains(deserializedCustomers);
FiddleHelper.WriteTable("2 - WhereBulkNotContains + Default Key", customers);
}
using (var context = new EntityContext())
{
// You can specify a custom `JOIN` clause with one or many properties using a `Lambda Expression`
var customers = context.Customers.WhereBulkNotContains(deserializedCustomers, x => x.Code);
FiddleHelper.WriteTable("3 - WhereBulkNotContains + Lambda Expression", customers);
}
using (var context = new EntityContext())
{
// You can specify a custom `JOIN` clause with one or many properties using a `List<string>`
var customers = context.Customers.WhereBulkNotContains(deserializedCustomers, new List<string> { "Code" });
FiddleHelper.WriteTable("4 - WhereBulkNotContains + Params string[]", customers);
}
using (var context = new EntityContext())
{
// You can specify a custom `JOIN` clause with one or many properties using a `params string[]`
var customers = context.Customers.WhereBulkNotContains(deserializedCustomers, "Code");
FiddleHelper.WriteTable("5 - WhereBulkNotContains + List<string>", customers);
}
}
// ## Scenario
// For example, you deserialize a JSON file into a list of `Customer` with the `CustomerID` populated, and you want to retrieve customers not contained in this list to deleted them.
{
using (var context = new EntityContext())
{
FiddleHelper.WriteTable("6 - Customers Before", context.Customers.AsNoTracking().ToList());
var customers = context.Customers.WhereBulkNotContains(deserializedCustomers);
context.Customers.RemoveRange(customers);
context.BulkSaveChanges();
FiddleHelper.WriteTable("7 - Customers After", context.Customers.AsNoTracking().ToList());
}
}
}
public static void SeedDatabase()
{
using (var context = new EntityContext())
{
var list = new List<Customer>();
for (int i = 0; i < 5; i++)
{
list.Add(new Customer() { Code = "Original_" + i, Email = "Original_" + i, FirstName = "Original_" + i, LastName = "Original_" + i });
}
context.BulkInsert(list);
}
}
public static string GetSerializedCustomers()
{
var customers = new List<Customer>();
for (int i = 0; i < 3; i++)
{
customers.Add(new Customer() { CustomerID = i + 1, Code = "Original_" + i, Email = "Updated_" + i, FirstName = "Updated_" + i, LastName = "Updated_" + i });
}
return JsonConvert.SerializeObject(customers);
}
public class EntityContext : DbContext
{
static EntityContext()
{
using (var context = new EntityContext())
{
context.Database.EnsureCreated();
}
}
public DbSet<Customer> Customers { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(new SqlConnection(FiddleHelper.GetConnectionStringSqlServer()));
base.OnConfiguring(optionsBuilder);
}
}
[Table("Customer")]
public class Customer
{
public int CustomerID { get; set; }
public string Code { get; set; }
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
}