将LiveData与包含的不同对象合并

时间:2018-01-26 04:33:34

标签: android android-room android-architecture-components android-livedata android-viewmodel

所以我正在使用Room和LiveData编写应用程序。这是一个财务应用程序。我有两个实体正在尝试合并,收款人交易交易有一个ForeignKey将其链接到收款人。我正在从Room一直使用LiveData(Daos,Repository,ViewModels)到我的UI(碎片)。

我想在达到Fragment级别之前将这两个数据集合在一起,但我不知道该怎么做。我知道我可以直接从数据库中创建一个带有查询的POJO,但我想要一个交易对象,其中包含收款人而不是两个中的所有字段。

有办法做到这一点吗?也许使用其中一个转换(map或switchMap)?或者也许使用MediatorLiveData?他们可以观察多种数据类型(例如LiveData和LiveData)吗?

Payee.java

@Entity
public class Payee {

    @PrimaryKey (autoGenerate = true)
    @ColumnInfo (name = "id")
    private int id;

    . . . 
}

Transaction.java

@Entity (foreignKeys =
        @ForeignKey(entity = Payee.class, 
                             parentColumns = "id", 
                             childColumns = "payee_id", 
                             onDelete = RESTRICT))
public class Transaction {

    @PrimaryKey (autoGenerate = true)
    @ColumnInfo (name = "id")
    private int id;

    @ColumnInfo (name = "payee_id")
    private int payeeId;
    @Ignore
    private Payee payee;

    . . .
}

1 个答案:

答案 0 :(得分:3)

其中包含Payee的交易对象将由@Embedded注释生成,与DAO查询中的其他列无关。

还有其他与您的问题相关的情景:

  • 需要完全独立查询的实体。将需要具有多个Source的MediatorLiveData。
  • 具有一对多关系的实体,使用@Relation注释生成的默认SELECT * FROM查询无法实现。可以使用Transformations.switchMap,如下所述(我在搜索时发现了你的问题)。

使用全局执行程序池,如带有AppExecutor类的Google GithubBrowserSample示例所示,存储库类中的嵌套查询最终将如下所示:

public LiveData<QuotationCustomer> loadQuotationDetails(int quotationId) {
    LiveData<QuotationCustomer> quotationLiveData =
            quotationDao.getQuotationCustomer(quotationId);
    LiveData<QuotationCustomer> result =
            Transformations.switchMap(quotationLiveData, quotation -> {
        MutableLiveData<QuotationCustomer> mutableResult = new MutableLiveData<>();
        appExecutors.diskIO().execute(() -> {
            quotation.quotationDetList = 
                    quotationDetDao.getQuotationDetsByQuotationIdSync(quotationId);
            mutableResult.postValue(quotation);
        });
        return mutableResult;
    });
    return result;
}

在上面的代码示例中,getQuotationDetsByQuotationIdSync DAO方法返回一个普通的List(不是LiveData&gt;),QuotationCustomer POJO扩展了@Entity带注释的类,并且quotationDetList属性定义如下:

@Ignore
public List<QuotationDetProductUnit> quotationDetList;

在您的情况下,按Payee替换QuotationCustomer,按交易替换QuotationDetProductUnit。