Android房间嵌入关系忽略where条件

Android房间嵌入关系忽略where条件,android,android-room,android-room-relation,Android,Android Room,Android Room Relation,我有一组带有@Relations的有点复杂的表。这是我的第一张桌子: @Entity(tableName = "commodity") class Commodity(@NotNull @PrimaryKey val id : String, val __typename : String, val name : String, val isometricDrawingUrl : String, va

我有一组带有@Relations的有点复杂的表。这是我的第一张桌子:

@Entity(tableName = "commodity")
class Commodity(@NotNull @PrimaryKey val id : String,
            val __typename : String,
            val name : String,
            val isometricDrawingUrl : String,
            val startDate : OffsetDateTime?,
            val endDate : OffsetDateTime?,
            val numberOfBlocks : Int,
            val numberOfRejects : Int)
第二张表:

@Entity(tableName = "milestone")
class Milestone(@NotNull @PrimaryKey val id : String,
            val commodityId : String,
            val __typename: String,
            val name: String,
            val earnableHours: Double,
            val currentStatusI18n: MilestoneStatus,
            val approved: OffsetDateTime?,
            val claimed: OffsetDateTime?
)
这是我的第一个@Embedded符号:

class CommoditiesAndAllMilestones {

    @Embedded
    var commodity: Commodity? = null

    @Relation(
    parentColumn = "id",
    entityColumn = "commodityId",
    entity = Milestone::class
    )
    var milestones: List<MileStonesAndAllBlocks> = ArrayList()

    override fun equals(other: Any?): Boolean {
        return this === other
    }

}
类别商品和所有里程碑{
@嵌入
var商品:商品?=空
@关系(
parentColumn=“id”,
entityColumn=“commodityId”,
实体=里程碑::类
)
var里程碑:List=ArrayList()
覆盖乐趣等于(其他:任何?):布尔值{
返回此===其他
}
}
第二种嵌入关系:

class MileStonesAndAllBlocks {

    @Embedded
    var milestone: Milestone? = null

    @Relation(
        entity = Block::class,
        parentColumn = "id",
        entityColumn = "milestoneId"
    )
    var blocks: List<Block> = ArrayList()

    @Relation(
        parentColumn = "id",
        entity = ApprovedBy::class,
        entityColumn = "milestoneId"
    )
    var approvedBy : List<ApprovedBy> = ArrayList()

    @Relation(
       parentColumn = "id",
       entity = ClaimedBy::class,
       entityColumn = "milestoneId"
    )
    var claimedBy : List<ClaimedBy> = ArrayList()

}
class MileStonesAndAllBlocks{
@嵌入
var里程碑:里程碑?=null
@关系(
实体=块::类,
parentColumn=“id”,
entityColumn=“milestoneId”
)
变量块:List=ArrayList()
@关系(
parentColumn=“id”,
实体=批准人::类,
entityColumn=“milestoneId”
)
var approvedBy:List=ArrayList()
@关系(
parentColumn=“id”,
entity=ClaimedBy::class,
entityColumn=“milestoneId”
)
var claimedBy:List=ArrayList()
}
问题是我无法进行简单的查询:

@Transaction
@Query("Select * from commodity WHERE name LIKE '%' || :typeName || '%' AND numberOfBlocks > 0")
fun getCommodities(typeName: String) : DataSource.Factory<Int,CommoditiesAndAllMilestones>
@事务
@查询(“从商品中选择*,商品名称如“%”| |:typeName |‘%”和numberOfBlocks>0”)
fun getproductions(typeName:String):DataSource.Factory
运行此查询将返回表中的所有值。它似乎忽略了where子句,尽管嵌入的关系工作列表结构与我预期的一样。如果使用房间关系,可以在where子句中设置条件吗

编辑

我已经创建了这个测试文件,显然您可以使用Where子句进行查询

@Query("Select * from commodity WHERE name LIKE '%' || :typeName || '%' AND numberOfBlocks > 0")
fun getCommoditiesBasic(typeName: String) : List<CommoditiesAndAllMilestones>

@RunWith(AndroidJUnit4::class)
class ListCategoryDaoTest  {

@get:Rule
val rule: TestRule = InstantTaskExecutorRule()

private lateinit var database: CommoditiesDatabase
private lateinit var commodityDao: CommodityDao
private lateinit var approvedBy : ApprovedByDao
private lateinit var claimedByDao : ClaimedByDao
private lateinit var blockDao : BlockDao
private lateinit var milestoneDao : MilestoneDao
private val workPackageId : String = UUID.randomUUID().toString()
private var workPackage : WorkPackageByIdQuery.WorkPackage? = null
private lateinit var commodityRepository : CommodityRepository
private val mainThreadSurrogate = newSingleThreadContext("UI thread")

@Before
fun setup() {
    database = CommoditiesDatabase.newTestInstance(InstrumentationRegistry.getInstrumentation().context)
    commodityDao = database.commodityDao()
    approvedBy = database.approvedByDao()
    claimedByDao = database.claimedByDao()
    blockDao = database.blockDao()
    milestoneDao = database.milestoneDao()
    commodityRepository = CommodityRepository(approvedBy,blockDao,claimedByDao,commodityDao,milestoneDao)

    Dispatchers.setMain(mainThreadSurrogate)

}

@Test
fun addAndRetrieveVideoDataAndBookmarks() {

    runBlocking {
        launch(Dispatchers.Unconfined) {
            workPackage = workPackage(workPackageId).response
            workPackage.let {
                if (it != null) {
                    for (commodity in it.commodities()) {
                        commodityRepository.insertCommodity(commodity)
                    }
                }
            }
            val commodityData = commodityDao.getCommoditiesBasic(CommodityType.SPOOL.rawValue())
            for (i in commodityData.indices) {
                val commodity = commodityData[i].commodity
                if (commodity != null) {
                    Assert.assertTrue(commodity.numberOfBlocks > 0)
                    Assert.assertTrue(commodity.name == CommodityType.SPOOL.rawValue())

                }
            }


        }

    }

}

@After
fun tearDown() {
    database.close()
    Dispatchers.resetMain() // reset main dispatcher to the original Main dispatcher
    mainThreadSurrogate.close()

}


fun workPackage(
    workPackageId: String
): BpsResponse<WorkPackageByIdQuery.WorkPackage, PipefighterError>
    {

        var totalBlocks = 0
        val workPackage: WorkPackageByIdQuery.WorkPackage
        val commodities = mutableListOf<WorkPackageByIdQuery.Commodity>()
        val crew = mutableListOf<WorkPackageByIdQuery.Crew>()


        val commodityNames = listOf(CommodityType.SPOOL, CommodityType.WELD, CommodityType.BULKPIPE)
        val milestoneTypes = listOf("Staged", "ELT", "Weldout", "Supports", "Punchlist")

        for (name in commodityNames) {
            val preIndex = commodityNames.indexOf(name) + 1
            // Create Commodities
            for (id in 1..8) {

                val milestones = mutableListOf<WorkPackageByIdQuery.Milestone>()
                for (index in 0 until 5) {

                    val status: MilestoneStatus
                    val blocks = if (id % 2 == 0 && milestoneTypes[index] == "Staged") {
                        totalBlocks++
                        status = MilestoneStatus.`$UNKNOWN`
                        listOf(WorkPackageByIdQuery.Block("Block", UUID.randomUUID().toString()))
                    } else {
                        status = MilestoneStatus.values()[Random.nextInt(4)]
                        listOf()
                    }

                    WorkPackageByIdQuery.Milestone(
                        "Milestone",
                        milestoneTypes[index],
                        Random.nextInt(101).toDouble(),
                        status,
                        if (status == MilestoneStatus.APPROVED) OffsetDateTime.now() else null,
                        if (status == MilestoneStatus.APPROVED) WorkPackageByIdQuery.ApprovedBy("ApprovedBy", UUID.randomUUID().toString(), "Mock Approver") else null,
                        if (status != MilestoneStatus.UNCLAIMED) OffsetDateTime.now() else null,
                        if (status != MilestoneStatus.UNCLAIMED) WorkPackageByIdQuery.ClaimedBy("ClaimedBy", UUID.randomUUID().toString(), "Mock Claimer") else null,
                        blocks
                    ).also {
                        milestones.add(it)
                    }
                }

                WorkPackageByIdQuery.Commodity(
                    "Commodity",
                    "1FX20000X-5D-130045-${String.format("%02d", preIndex)}-${String.format("%02d", id)}",
                    name.rawValue(),
                    "https://file-examples.com/wp-content/uploads/2017/10/file-sample_150kB.pdf",
                    OffsetDateTime.now().plusDays(id - 1L),
                    OffsetDateTime.now().plusDays(id + 1L),
                    milestones
                ).also {
                    commodities.add(it)
                }
            }
        }

        // Create Crew
        for (id in 1..3) {
            WorkPackageByIdQuery.Crew(
                PipefighterClient.TYPE_CREW,
                UUID.randomUUID().toString(),
                "# $id Mock Tester"
            ).also {
                crew.add(it)
            }
        }

        WorkPackageByIdQuery.WorkPackage(
            PipefighterClient.TYPE_WORKPACKAGE,
            workPackageId,
            OffsetDateTime.now(),
            "https://file-examples.com/wp-content/uploads/2017/10/file-sample_150kB.pdf",
            OffsetDateTime.now(),
            OffsetDateTime.now().plusMonths(1),
            totalBlocks,
            0,
            commodityNames,
            commodities,
            crew
        ).also {
            workPackage = it
        }

        return BpsResponse(workPackage, null)
    }


}
@Query(“从商品中选择*,商品名称如“%”和numberOfBlocks>0”)
fun getCommoditiesBasic(typeName:String):列表
@RunWith(AndroidJUnit4::类)
类ListCategoryDaoTest{
@获取:规则
val规则:TestRule=InstantTaskExecutorRule()
私有lateinit var数据库:CommoditiesDatabase
私有lateinit var commodityDao:commodityDao
私有lateinit变量approvedBy:ApprovedByDao
私有lateinit变量claimedByDao:claimedByDao
私有lateinit var blockDao:blockDao
私有lateinit var milestoneDao:milestoneDao
private val workPackageId:String=UUID.randomUUID().toString()
私有var工作包:WorkPackageByIdQuery.workPackage?=null
私有lateinit var commodityRepository:commodityRepository
private val mainthreadsprogate=newSingleThreadContext(“UI线程”)
@以前
趣味设置(){
database=CommoditiesDatabase.newTestInstance(InstrumentationRegistry.getInstrumentation().context)
commodityDao=数据库。commodityDao()
approvedBy=数据库。approvedByDao()
claimedByDao=database.claimedByDao()
blockDao=database.blockDao()
milestoneDao=database.milestoneDao()
commodityRepository=commodityRepository(批准人、blockDao、claimedByDao、commodityDao、milestoneDao)
Dispatchers.setMain(mainthreadsubrogate)
}
@试验
趣味添加和检索视频数据和书签(){
运行阻塞{
下水(调度员,无限制){
workPackage=workPackage(workPackageId)。响应
workPackage.let{
如果(it!=null){
for(it.productions()中的商品){
商品存储。插入商品(商品)
}
}
}
val commodityData=commodityDao.getCommoditiesBasic(CommodityType.SPOOL.rawValue())
用于(i在商品数据索引中){
val商品=商品数据[i]。商品
if(商品!=null){
Assert.assertTrue(commodity.numberOfBlocks>0)
Assert.assertTrue(commodity.name==CommodityType.SPOOL.rawValue())
}
}
}
}
}
@之后
有趣的撕裂{
database.close()
Dispatchers.resetMain()//将主调度器重置为原始主调度器
mainthreadsrogate.close()
}
趣味工作包(
工作包ID:字符串
):bps响应
{
var totalBlocks=0
val workPackage:WorkPackageByIdQuery.workPackage
val商品=mutableListOf()
val crew=mutableListOf()
val commodityNames=listOf(CommodityType.SPOOL、CommodityType.WELD、CommodityType.BULKPIPE)
val milestoneTypes=listOf(“分段”、“ELT”、“焊接”、“支撑”、“Punchlist”)
for(商品名称){
val preIndex=commodityNames.indexOf(名称)+1
//创造商品
for(1..8中的id){
val里程碑=mutableListOf()
for(索引在0到5之间){
val状态:MilestoneStatus
val blocks=if(id%2==0&&milestoneTypes[索引]==“暂存”){
总积木++
状态=MilestoneStatus.`$UNKNOWN`
listOf(WorkPackageByIdQuery.Block(“Block”,UUID.randomUUID().toString())
}否则{
status=MilestoneStatus.values()[Random.nextInt(4)]
清单(
}
WorkPackageByIdQuery.Milestone(
“里程碑”,
milestoneTypes[索引],
Random.nextInt(101).toDouble(),
地位
如果(status==MilestoneStatus.APPROVED)OffsetDateTime.now()否则为空,
如果(status==MilestoneStatus.APPROVED)WorkPackageByIdQuery.ApprovedBy(“ApprovedBy”,UUID.randomUUID().toString(),“模拟批准人”)为空,
如果(status!=MilestoneStatus.unclaim)OffsetDateTime.now()否则为空,
如果(状态!=MilestoneStatus.unclaims)工作包byidquery.ClaimedBy(“ClaimedBy”,UUID.randomUUID().toString(),“Moc
fun addSomeTestingData() {
    mAllDao.deleteAllBlocks()
    mAllDao.deleteAllClaimedBys()
    mAllDao.deleteAllApprovedBys()
    mAllDao.deleteAllMileStones()
    mAllDao.deleteAllCommodities()
    val ab = ApprovedBy()
    ab.approvedBy = "Fred"
    ab.milestoneId = "M2"
    mAllDao.insertOneApprovedByRow(ab)
    ab.approvedBy = "Mary"
    ab.milestoneId = "M1"
    mAllDao.insertOneApprovedByRow(ab)
    ab.approvedBy = "Jane"
    ab.milestoneId = "M2"
    mAllDao.insertOneApprovedByRow(ab)

    val cb = ClaimedBy()
    cb.claimedBy = "Susan"
    cb.milestoneId = "M1"
    mAllDao.insertOneClaimedByRow(cb)
    cb.claimedBy = "Helen"
    cb.milestoneId = "M2"
    mAllDao.insertOneClaimedByRow(cb)
    cb.claimedBy = "Tom"
    cb.milestoneId = "M1"
    mAllDao.insertOneClaimedByRow(cb)

    val c1 = Commodity("C1","Typ1","C1T1","blah","2019-01-01","2019-03-01",10,0)
    mAllDao.insertOneCommodityRow(c1)
    val c2 = Commodity("C2","Typ2","C2T2","more blah","2019-01-20","2019-01-31",5,1)
    mAllDao.insertOneCommodityRow(c2)
    val c3 = Commodity("C3","Typ1","C3T1","blah blah","2019-01-15","2019-02-16",7,2)
    mAllDao.insertOneCommodityRow(c3)

    val m1 = Milestone("M1","C1","Typ1","M1C1T1",75.5,"INPROGRESS","2019-01-17","2")
    mAllDao.insertOneMilestoneRow(m1)
    val m2 = Milestone("M2","C2","Typ1","M2C3T1",35.6,"READY","2019-01-15","1")
    mAllDao.insertOneMilestoneRow(m2)

    val blk = Block()
    blk.block = "M1B1"
    blk.milestoneId = "M1"
    mAllDao.insertOneBlockRow(blk)
    blk.block = "M1B2"
    blk.milestoneId = "M1"
    mAllDao.insertOneBlockRow(blk)
    blk.block = "M1B3"
    blk.milestoneId = "M1"
    mAllDao.insertOneBlockRow(blk)
    blk.block = "M2B1"
    blk.milestoneId = "M2"
    mAllDao.insertOneBlockRow(blk)
    blk.block = "M2B2"
    blk.milestoneId = "M2"

}
fun logCommoditiesAndMilstones(cmlist: List<CommoditiesAndAllMilestones>) {
    for (cm: CommoditiesAndAllMilestones in cmlist) {
        Log.d("CAMINFO","CommodityID is " + cm.commodity?.id)
        for (mab: MileStonesAndAllBlocks in cm.milestones) {
            if (mab.milestone != null) {
                Log.d("CAMINFO","\n\tMilestone is " + mab.milestone?.id)
            }
            for (b: Block in mab.blocks) {
                Log.d("CAMINFO","Block ID is " + b.id + " value is " + b.block)
            }
            for (ab: ApprovedBy in mab.approvedBy) {
                Log.d("CAMINFO","APPRV BY " + ab.approvedBy)
            }
            for (cb: ClaimedBy in mab.claimedBy) {
                Log.d("CAMINFO","CLMD BY " + cb.claimedBy)
            }
        }
    }
}
@Transaction
@Query("Select * from commodity WHERE name LIKE '%' || :typeName || '%' AND numberOfBlocks > 0")
fun getCommodities(typeName: String) : List<CommoditiesAndAllMilestones>
    mAppDatabase = Room.databaseBuilder(this,AppDatabase::class.java,"commodities")
        .allowMainThreadQueries()
        .build()
    mAllDao = mAppDatabase.allDao()

    addSomeTestingData()
    var cmlist: List<CommoditiesAndAllMilestones> = mAllDao.getCommodities("C2") //<<<<<<<<< 1st Query
    logCommoditiesAndMilstones(cmlist)
    cmlist = mAllDao.getCommodities("C1") //<<<<<<<<<< 2nd Query
    logCommoditiesAndMilstones(cmlist)
2019-10-23 14:28:34.709 D/CAMINFO: CommodityID is C2
2019-10-23 14:28:34.709 D/CAMINFO:  Milestone is M2
2019-10-23 14:28:34.709 D/CAMINFO: Block ID is 24 value is M2B1
2019-10-23 14:28:34.709 D/CAMINFO: APPRV BY Fred
2019-10-23 14:28:34.709 D/CAMINFO: APPRV BY Jane
2019-10-23 14:28:34.709 D/CAMINFO: CLMD BY Helen


2019-10-23 14:28:34.716 D/CAMINFO: CommodityID is C1
2019-10-23 14:28:34.716 D/CAMINFO:  Milestone is M1
2019-10-23 14:28:34.717 D/CAMINFO: Block ID is 21 value is M1B1
2019-10-23 14:28:34.717 D/CAMINFO: Block ID is 22 value is M1B2
2019-10-23 14:28:34.717 D/CAMINFO: Block ID is 23 value is M1B3
2019-10-23 14:28:34.717 D/CAMINFO: APPRV BY Mary
2019-10-23 14:28:34.717 D/CAMINFO: CLMD BY Susan
2019-10-23 14:28:34.717 D/CAMINFO: CLMD BY Tom