Reputation: 159
I start using BLToolkit and there is a new advantage: InsertOrReplace When I try to use it there is an exception: "InsertOrUpdate method does not support identity field 'Margin.id'" My Model here:
[TableName("Margin")]
public class Margin
{
[PrimaryKey, Identity] public int id;
[NotNull] public string StoreID;
[PrimaryKey] public int? PrTypeID;
public decimal MarginRate;
[Association(ThisKey = "PrTypeID", OtherKey = "ProductID", CanBeNull = true)] public Product Product;
}
Call the method:
db.InsertOrReplace(new CSSWarranty.DataModel.DataModel.Margin()
{
MarginRate = newMargin.Margin,
PrTypeID = newMargin.ProductTypeID == 0 ? null : newMargin.ProductTypeID,
StoreID = newMargin.StoreID,
id = newMargin.MarginID
});
May be someone can say how to use the next construction: db.Margin.InsertOrUpdate(x,y) All regards!
I don't understand why this example is working:
[TableName("Notification")]
public class Notification
{
[PrimaryKey] public string NotificationID;
public string Note;
}
Call:
var db = new RetailerDb()
db.InsertOrReplace(new DataModel.DataModel.Notification()
{
Note = note,
NotificationID = "ConfirmNote"
});
DB class:
private var db = new RetailerDb();
public class RetailerDb : DbManager
{
public RetailerDb() : base("DBConnection")
{
}
public Table<DataModel.Margin> Margin
{
get { return GetTable<DataModel.Margin>(); }
}
}
Upvotes: 3
Views: 2338
Reputation: 32571
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
.
Upvotes: 2