Как использовать InsertOrReplace в BLToolkit.3

Я начинаю использовать BLToolkit, и у меня есть новое преимущество: InsertOrReplace. Когда я пытаюсь его использовать, возникает исключение: «Метод InsertOrUpdate не поддерживает поле идентификации« Margin.id »». Моя модель здесь:

[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;

    }

Вызовите метод:

 db.InsertOrReplace(new CSSWarranty.DataModel.DataModel.Margin()
                                      {
                                          MarginRate = newMargin.Margin,
                                          PrTypeID = newMargin.ProductTypeID == 0 ? null : newMargin.ProductTypeID,
                                          StoreID = newMargin.StoreID,
                                          id = newMargin.MarginID
                                      });

Может кто подскажет, как использовать следующую конструкцию: db.Margin.InsertOrUpdate(x,y) Всем привет!

Я не понимаю, почему этот пример работает:

[TableName("Notification")]
    public class Notification
    {
        [PrimaryKey]    public      string NotificationID;
                        public      string     Note;
    }

Вызов:

 var db = new RetailerDb()
db.InsertOrReplace(new DataModel.DataModel.Notification()
                              {
                                  Note = note,
                                  NotificationID = "ConfirmNote"
                               });

Класс БД:

private var db = new RetailerDb();

public class RetailerDb : DbManager
{
    public RetailerDb() : base("DBConnection")
    {
    }

    public Table<DataModel.Margin> Margin
    {
        get { return GetTable<DataModel.Margin>(); }
    }
}

person user1706449    schedule 14.12.2012    source источник
comment
Уместна ли здесь чувствительность к регистру, то есть Margin.id != Margin.ID?   -  person Alex Filipovici    schedule 14.12.2012
comment
поля в сопоставлении имеют аналогичный регистр в базе данных (базе данных) id = (сопоставление) id, если у вас есть рабочий пример с InsertOrReplace - пожалуйста, предоставьте его нам   -  person user1706449    schedule 14.12.2012
comment
Каков класс объекта db в вашем коде?   -  person Alex Filipovici    schedule 14.12.2012


Ответы (1)


До сих пор мне удалось узнать из bltoolkit/Source/Data/Linq/Query.cs класс:

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);
    }
    ...
}

Статический метод вызывается из bltoolkit/Source/ Класс Data/Linq/Extensions.cs:

public static int InsertOrReplace<T>(this IDataContext dataContext, T obj)
{
    return Query<T>.InsertOrReplace(DataContextInfo.Create(dataContext), obj);
}

Похоже, что поля Identity вызывают исключение.

[PrimaryKey, Identity]    public int      id; //remove this field or change the column definition

[ИЗМЕНИТЬ]

Посмотрите, как определены следующие классы:

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
}

А вот пример использования в тестовом методе:

[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);
        }
    });
}

Вы можете видеть, что InsertOrUpdate не используется для класса Person, но используется для класса Patient. Таким образом, этот метод поддерживается только при передаче полей, отличных от Identity.

Примечание. InsertOrUpdate устарел, но все еще используется в тестах исходного кода проекта. Тем не менее, это не должно иметь никакого значения, просто считайте, что это InsertOrReplace.

person Alex Filipovici    schedule 14.12.2012