-
Notifications
You must be signed in to change notification settings - Fork 108
Usage
The samples below will assume a database with the following tables:
public class Country
{
public int ID { get; set; }
[Required, StringLength(50)]
public string Name { get; set; }
[Required, StringLength(2)]
public string ISO { get; set; }
public DateTime Created { get; set; }
public DateTime Updated { get; set; }
}
public class PageVisit
{
public int ID { get; set; }
public int UserID { get; set; }
public DateTime Date { get; set; }
public int Visits { get; set; }
public DateTime FirstVisit { get; set; }
public DateTime LastVisit { get; set; }
}We'll also reference the following variables, which will assume these initial values:
var newCountry = new Country
{
Name = "Australia",
ISO = "AU",
};
var newVisit = new DailyVisit
{
UserID = userID,
Date = DateTime.UtcNow.Date,
Visits = 1,
};To access the Upsert extension methods, you'll have to make sure to add this reference to your usings:
using Microsoft.EntityFrameworkCore;A typical upsert call using the library will look something like this:
DataContext.Countries.Upsert(newCountry)
.On(c => c.ISO)
.WhenMatched(c => new Country
{
Name = "Australia"
Updated = DateTime.UtcNow,
})
.RunAsync();The Upsert call parameter will be used to insert new entries to the table, the On call parameter is used to identify the columns used to find matching rows. If a matching row is found, it will be updated using the parameter to the WhenMatched call. Note that this last call receives a new instance of Country, rather than updating the existing one
Both the On and the WhenMatched calls can be omitted. If the On call is not made, the matching will be done on the primary key on the table. If the WhenMatched call is omitted, the upsert command will update all the remaining calls on the table, which are not marked as primary keys or are auto generated.
Sometimes you might want to update a column based on the current value in the table. For example, if you want to increment a column.
You can use the following syntax:
You can also see how to implement the multi column record matching:
DataContext.DailyVisits.Upsert(newVisit)
.On(v => new { v.UserID, v.Date })
.WhenMatched(v => new DailyVisit
{
Visits = v.Visits + 1,
})
.RunAsync();In the same way, you can insert multiple entities in one call. Keep in mind that each database engine has a limit of how many parameters a query can be passed. Since each property will use up a variable, this should only be used with smaller datasets. For larger datasets an alternative approach may be needed.
DataContext.Countries.UpsertRange(newCountries)
.On(c => c.ISO)
.RunAsync();Finally, you can easily access values from the "insert" dataset within the update clause, by adding a second expression parameter, like follows:
DataContext.Countries.Upsert(newCountry)
.On(c => c.ISO)
.WhenMatched((cDb, cIns) => new Country
{
Name = cIns.Name,
Updated = DateTime.UtcNow,
})
.RunAsync();