Question

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>(); }
    }
}
Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top