So far I've managed to find out from the bltoolkit / Source / Data / Linq / Query.cs class:
public static int InsertOrReplace(IDataContextInfo dataContextInfo, T obj)
{
...
else if (field.IsIdentity)
{
throw new LinqException("InsertOrUpdate method does not support identity field '{0}.{1}'.", sqlTable.Name, field.Name);
}
...
}
The static method is called from the bltoolkit / Source / Data / Linq / Extensions.cs class:
public static int InsertOrReplace<T>(this IDataContext dataContext, T obj)
{
return Query<T>.InsertOrReplace(DataContextInfo.Create(dataContext), obj);
}
It seems that Identity
fields raise an exception.
[PrimaryKey, Identity] public int id; //remove this field or change the column definition
[EDIT]
Take a look at how the following classes are defined:
public class Patient
{
[PrimaryKey]
public int PersonID;
public string Diagnosis;
//more class definition
}
public class Person
{
//some class definition
[Identity, PrimaryKey]
//[SequenceName("PostgreSQL", "Seq")]
[SequenceName("Firebird", "PersonID")]
[MapField("PersonID")] public int ID;
public string FirstName { get; set; }
public string LastName;
[Nullable] public string MiddleName;
public Gender Gender;
[MapIgnore] public string Name { get { return FirstName + " " + LastName; }}
[Association(ThisKey = "ID", OtherKey = "PersonID", CanBeNull = true)]
public Patient Patient;
//more class definition
}
And here is the sample usage in a test method:
[Test]
public void InsertOrUpdate1()
{
ForEachProvider(db =>
{
var id = 0;
try
{
id = Convert.ToInt32(db.Person.InsertWithIdentity(() => new Person
{
FirstName = "John",
LastName = "Shepard",
Gender = Gender.Male
}));
for (var i = 0; i < 3; i++)
{
db.Patient.InsertOrUpdate(
() => new Patient
{
PersonID = id,
Diagnosis = "abc",
},
p => new Patient
{
Diagnosis = (p.Diagnosis.Length + i).ToString(),
});
}
Assert.AreEqual("3", db.Patient.Single(p => p.PersonID == id).Diagnosis);
}
finally
{
db.Patient.Delete(p => p.PersonID == id);
db.Person. Delete(p => p.ID == id);
}
});
}
You can see that there is no usage of InsertOrUpdate
for the Person
class, but there is for the Patient
class. So, the method is supported only when you pass in non-Identity
fields.
Note: InsertOrUpdate
is obsolete but it's still being used in the tests in the project source code. Still, it should have no impact, just think of it as InsertOrReplace
.