首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从聊天室DB返回项目计数

从聊天室DB返回项目计数
EN

Stack Overflow用户
提问于 2019-06-21 04:25:31
回答 1查看 325关注 0票数 1

如果某个父对象具有通过外键关联的子对象,我正在尝试阻止从Room DB中删除该父对象。

我正在做一个学位追踪器。如果某个学期有课程,则不能删除该学期。如果该学期没有课程,则可以删除该学期。我正在尝试获得具有相关术语id的课程计数,并使用一个简单的if语句来删除该术语,如果没有课程,则使用弹出警报,如果该术语有课程,并指示用户在删除该术语之前删除该课程。

来自TermEditorActivity.java

代码语言:javascript
复制
switch(item.getItemId()){
...
case R.id.delete_term:

int coursecount = queryCourses(termIdSelected);

    if(coursecount > 0){
                    AlertDialog.Builder a_builder = new 
                    AlertDialog.Builder(TermEditorActivity.this);
                    a_builder.setMessage("Courses are assigned for this 
                    term!\n\nYou must remove all courses" +
                            "prior to deleting this term.")
                            .setCancelable(false)
                            .setPositiveButton("Okay", new 
                             DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, 
                                int which) {

                                    finish();
                                }
                            });
                    AlertDialog deleteAllAlert = a_builder.create();
                    deleteAllAlert.setTitle("CANNOT DELETE TERM!!!");
                    deleteAllAlert.show();
                    return true;
                }else{
                    mViewModel.deleteTerm();
                    startActivity(new Intent(TermEditorActivity.this, 
                    MainActivity.class));
                }
...
public int queryCourses(int term) {
        int course = mViewModel.queryCourses(term);
        return course;
    }

在ViewModel中:

代码语言:javascript
复制
public int queryCourses(final int term) {
        int course = mRepository.queryCourses(term);
        return course;
    }

来自AppRepository (这就是我认为事情分崩离析的地方):

代码语言:javascript
复制
public int queryCourses(final int term) {
//        executor.execute(new Runnable() {
//            @Override
//            public void run() {
              return count = courseDb.termDao().queryCourses(term);
//            }
//        });
//            return count;
//        }

or with threading:

 public int queryCourses(final int term) {
        executor.execute(new Runnable() {
            @Override
            public void run() {
              count = courseDb.termDao().queryCourses(term);
            }
        });
            return count;
        }

来自TermDAO:

代码语言:javascript
复制
@Query("SELECT COUNT(*) FROM course WHERE term_id = :termIdSelected")
    int queryCourses(int termIdSelected);

这会导致运行时错误,当按下delete按钮时,它会崩溃。概念很简单-使用术语的id查询course DB,以获得具有术语id外键的课程数量。如果没有,请删除该术语并返回到术语列表。如果有课程(count > 0),则提醒用户,并在不删除的情况下完成。

不带线程的异常:

代码语言:javascript
复制
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.

当使用线程时,它会删除包含或不包含课程的术语,并且当有课程附加到该术语时,不会出现警告。在调试模式下运行时,如果有一个课程,则coursecount返回0,因此查询未正确运行。

是否需要做些什么才能从线程中获取值?

以下是为RESTRICT约束抛出SQLiteConstraintException时运行时错误的崩溃日志。即使在使用Exception时也不会被捕获。

代码语言:javascript
复制
E/AndroidRuntime: FATAL EXCEPTION: pool-1-thread-1
    Process: com.mattspriggs.termtest, PID: 23927
    android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 1811 SQLITE_CONSTRAINT_TRIGGER)
        at android.database.sqlite.SQLiteConnection.nativeExecuteForChangedRowCount(Native Method)
        at android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java:784)
        at android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java:754)
        at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64)
        at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeUpdateDelete(FrameworkSQLiteStatement.java:45)
        at android.arch.persistence.room.EntityDeletionOrUpdateAdapter.handle(EntityDeletionOrUpdateAdapter.java:70)
        at com.mattspriggs.termtest.database.TermDao_Impl.deleteTerm(TermDao_Impl.java:144)
        at com.mattspriggs.termtest.database.AppRepository$4.run(AppRepository.java:83)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)
EN

回答 1

Stack Overflow用户

发布于 2019-06-21 04:51:19

Room实际上支持此行为:

在定义子实体的foreign键时,您只需以这种方式将操作onDelete设置为RESTRICT,而父实体具有与其相关的子项则无法删除。

你的子类应该是这样的:

代码语言:javascript
复制
@Entity(tableName = "child_table",foreignKeys ={
    @ForeignKey(onDelete = RESTRICT,entity = ParentEntity.class,
    parentColumns = "uid",childColumns = "parentId")},
    indices = {
            @Index("parentId"),
    })
public class ChildEntity {
    @PrimaryKey
    public String id;
    public String parentId;
}

你的父类看起来像这样:

代码语言:javascript
复制
@Entity
public class ParentEntity{
    @PrimaryKey
    public String uid;
}

有关如何定义外键的详细信息,请查看here

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56693432

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档