Комната, использующая аннотацию @Relation - отношение один ко многим, где отношение дочернего элемента предложения

Использование аннотации @Relation. Я могу запросить отношение «один ко многим», используя следующее:

 @Dao
 public interface PostDao {
        @Query("SELECT * FROM post")
        List<PostWithComments> getPostWithComments();
 }

Вот сущности

@Entity
public class Post {
    @PrimrayKey
    private int id;
    private String title;
    private String content;
}

@Entity
public class Comment {
    @PrimrayKey
    private int id;
    private int post_id;
    private String content;
    private String status;
}


public class PostWithComments {
    @Embedded
    public Post post;

    @Relation(parentColumn = "id", entityColumn = "post_id", entity = Comment.class)
    public List<Comment> comments;

}

Я хотел бы получить все сообщения, которые имеют комментарий с status = approved, но я не совсем уверен, как комната справляется с этим. Я пробовал следующее:

 @Dao
 public interface PostDao {
        @Query("SELECT * FROM post INNER JOIN comment ON post.id = comment.post_id WHERE comment.status = 'approved'")
        List<PostWithComments> getPostWithComments();
 }

У меня есть дубликаты в результатах. Каждый пост появляется несколько раз в List<PostWithComments> результатах.

Обновлять:

После прочтения сгенерированного кода в PostDao_Impl.java кажется, что Room выполняет подзапрос для получения отношения.

Сначала он выполняет запрос в аннотации @Query из метода getPostWithComments, а затем генерирует подзапрос для отношения для заполнения List<Comment>

SELECT id, post_id, title, content FROM comment WHERE post_id IN ( и некоторая другая логика, и, похоже, нет способа изменить сгенерированный подзапрос.

Есть ли другой способ сделать это?

А пока, может быть, вы сможете отфильтровать полученные комментарии.

uan 03.06.2019 16:48

@uan это то, что я делаю, но в идеале я должен иметь возможность фильтровать их в запросе.

someone 03.06.2019 22:29
4
2
1 294
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Не проверено, но вы можете попробовать это...

public class PostWithComments {
    @Embedded
    public Post post;

    @Embedded
    public Comment comment;
}



@Dao
public interface PostWithCommentsDao {
       @Query("SELECT post.*, comment.* FROM post LEFT JOIN comment ON post.id=comment.post_id where comment.status = 'approved'")
       List<PostWithComments> getPostWithComments();
}

Как это должно работать? Каждый пост имеет несколько комментариев, а не один. Объект PostWithComments должен иметь один пост и список комментариев.

someone 31.05.2019 09:30
Ответ принят как подходящий

С @Relation вы можете использовать @DatabaseView

@DatabaseView("SELECT * FROM comments WHERE status = 'approved'")
public class ApprovedComment {
  @Embedded
  Comment comment;
}

Класс PostWithComments

public class PostWithComments {
    @Embedded
    public Post post;

    @Relation(parentColumn = "id", entityColumn = "post_id", entity = ApprovedComment.class)
    public List<ApprovedComment> comments;

}

ДАО

@Dao
public interface PostWithCommentsDao {
       @Query("SELECT * FROM post")
       List<PostWithComments> getPostWithComments();
}

Вам также необходимо обновить класс базы данных, который расширяет RoomDatabase, и вам может потребоваться обновить версию.

@Database(entities = {Post.class, Comment.class}, views = {ApprovedComment.class}, version = 1)
public abstract class MyDatabase extends RoomDatabase

Отличный ответ, отлично работает. Обратите внимание, что это также способ использования предложения Сортировать по для дочерних сущностей в отношении: добавьте порядок в запрос DatabaseView.

Ronan 12.02.2020 09:55

Другие вопросы по теме