Несколько первичных ключей - ORMlite

Я создал базу данных, для моего приложения android, ведьма имеет 16 таблиц. Я хочу использовать отображение ORMlite. Проблема в том, что я не нашел примеров, когда у вас есть составной идентификатор(несколько первичных ключей). Например у меня есть таблица:

CREATE  TABLE IF NOT EXISTS `Tourist_Guide`.`Cultural_activity` (
  `City_Id` INT NOT NULL ,
  `activity_Id` INT NOT NULL ,
  `Cultural_activity_Id` INT NOT NULL AUTO_INCREMENT ,
  `Name_Of_Cultural_activity` VARCHAR(30) NOT NULL ,
  PRIMARY KEY (`Cultural_activity_Id`, `City_Id`, `activity_Id`) ,
  INDEX `fk_Cultural_activity_activity1` (`City_Id` ASC, `activity_Id` ASC) ,
  CONSTRAINT `fk_Cultural_activity_activity1`
    FOREIGN KEY (`City_Id` , `activity_Id` )
    REFERENCES `Tourist_Guide`.`activity` (`City_Id` , `activity_Id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

можете ли вы, пожалуйста, сказать мне, как сопоставить эту таблицу с классом (как должен выглядеть этот класс), это возможно?

4 ответов


ограничения

для простоты и возможности сохранения одного и того же класса POCO в db4o, memcached, redis или в файловой системе (т. е. поставщики, включенные в ServiceStack), каждая модель должна иметь один первичный ключ, по соглашению OrmLite ожидает, что это будет Id, хотя вы используйте атрибут [Alias("DbFieldName")] сопоставьте его со столбцом с другое имя или используйте атрибут [PrimaryKey], чтобы сообщить OrmLite использовать другое свойство для основного ключ.

вы все еще можете выбрать из этих таблиц, вы просто не сможете используйте API, которые полагаются на него, например Update или Delete, где фильтр подразумевается (т. е. не указан), все API, которые заканчиваются ById и др.

обходной путь ограничение одного первичного ключа

потенциальным обходным путем для поддержки таблиц с несколькими первичными ключами является создать автоматически сгенерированный код, который возвращает уникальное значение на основе всего первичного ключа fields, e.g:

public class OrderDetail
{
    public string Id { get { return this.OrderId + "/" + this.ProductId; } }



public int OrderId { get; set; }
    public int ProductId { get; set; }
    public decimal UnitPrice { get; set; }
    public short Quantity { get; set; }
    public double Discount { get; set; }
}

https://github.com/ServiceStack/ServiceStack.OrmLite/#limitations


вы должны использовать следующую аннотацию над каждым уникальным полем:

@DatabaseField (uniqueCombo = true)

вот документы на uniqueCombo.


можно создать искусственное поле ID, которое состоит из композиции других полей. Это можно сделать с помощью настроек useSetGet собственность в @DatabaseField Аннотация к true. Это заставляет ORMLite вызывать методы getter и setter вместо использования отражения.

в вашем геттере вы можете затем вернуть композицию своих полей.

Это будет выглядеть в вашем пример:

@DatabaseField(id=true, useGetSet=true)
private String id;

...

public String getId(){

    return culturalAcitivityId +"-" +cityId +"-" +activityId;

}
public void setId(String id){

    this.id = id;

}

http://ormlite.com/javadoc/ormlite-core/com/j256/ormlite/field/DatabaseField.html#useGetSet()


OrmLite ServiceStack по дизайну не поддерживает несколько составных первичных ключей. Для того, чтобы ваши же POCOs были полезны вне БД (например, хранилища данных NoSQL, поставщики кэша и т. д.), OrmLite ожидает один первичный ключ для каждого типа, который по умолчанию является Id свойство (переопределяется классом ModelConfig или [PrimaryKey], [Alias] атрибуты).

обходные пути для преодоления этого ограничения включают создание единого уникального идентификатора, но включают уникальный ограничение на составные первичные ключи, e.g:

[CompositeIndex("CompositePkId1","CompositePkId2", Unique = true)] 
public class Poco 
{
    [AutoIncrement]
    public int Id { get; set; }
    public int CompositePkId1 { get; set; }
    public int CompositePkId2 { get; set; }
}

или создание псевдо-столбца, содержащего комбинацию всех первичных ключей, e.g:

public class Poco 
{
    public string Id { get { return CompositePkId1 + ":" + CompositePkId2; } }
    public int CompositePkId1 { get; set; }
    public int CompositePkId2 { get; set; }
}