GreenDAO не генерирует ограничение FOREIGN KEY (...) в таблице

Когда я создаю двунаправленную связь 1: n, как показано ниже, генератор не использует никаких ограничений FOREIGN KEY (...) в таблице.

entity customer = schema.addEntity("Customer");
customer.addIdProperty();
customer.addStringProperty("name").notNull();

Entity order = schema.addEntity("Order");
order.setTableName("ORDERS"); // "ORDER" is a reserved keyword
order.addIdProperty();
Property orderDate = order.addDateProperty("date").getProperty();
Property customerId = order.addLongProperty("customerId").notNull().getProperty();
order.addToOne(customer, customerId);

customer.addToMany(order, customerId);

Это нормально? Предполагается ли он генерировать ограничения FOREIGN KEY (...) в таблице или выполняется ли это только во время выполнения через код?

Ответ 1

Я работал в одном и том же выпуске, работая над проектом.

Просматривая сгенерированный код DaoGenerator, ограничения внешнего ключа не генерируются даже с использованием отношения ToMany.

Я попытался добавить ограничение внешнего ключа вручную в запросе в каждой сущности DAO, и все же это не решило проблему.

Ссылаясь на документацию sqlite, я обнаружил, что внешний ключ не применяется по умолчанию. Вы должны запустить запрос PRAGMA foreign_keys = ON; для каждого соединения, созданного в базе данных. Я проверил его из оболочки adb. Внешний ключ был введен после выполнения запроса PRAGMA.

Последняя проблема заключалась в том, чтобы найти место для этого кода в проекте, чтобы он выполнялся для каждого сеанса.

Решение находится в классе DaoSession, сгенерированном проектом DaoGenerator

вставить

 if(!db.isReadOnly()){
     db.execSQL("PRAGMA foreign_keys = ON;");
 }

в конце конструктора.

Не забудьте вручную добавить ограничение внешнего ключа в создании табличных запросов для каждого DAO, имеющего свойство внешнего ключа.

Ответ 2

order.addToOne(клиент, customerId);

является правильным, и он создает отношения fk с таблицей клиентов. но следующее утверждение

customer.addToMany(заказ, customerId);

недействителен, поскольку в таблицу клиента не добавлено свойство (customerId)

поэтому в этом случае, если вы хотите создать отношение to-many к таблице клиентов, используйте

addToMany (sourceProperty, target, targetProperty). Но, на мой взгляд, нет необходимости в customer.addToMany(order, customerId)

Ответ 3

вы можете напрямую написать createTable(){} в XXXXDao,

public static void createTable(Database db, boolean ifNotExists) {
    String constraint = ifNotExists? "IF NOT EXISTS ": "";
    String sql = "CREATE TABLE " + constraint + "\"PERSONGROUPS\" (" + //
                "\"_id\" INTEGER PRIMARY KEY ," + // 0: id
                "\"PID\" TEXT," + // 1: pid
                "\"GROUP_ID\" INTEGER," +
                "FOREIGN KEY(\"PID\") REFERENCES PERSONS(\"PID\") ON DELETE CASCADE," +
                "FOREIGN KEY(\"GROUP_ID\") REFERENCES GROUPS(\"_id\") ON DELETE CASCADE)";
    Log.v("PersonGroupDao", sql);
    db.execSQL(sql); // 2: group_id
}

и вы должны запустить db.execSQL("PRAGMA foreign_keys = ON;");