简体   繁体   English

查询返回的列在 db.unitlocalized.future.MetricSimpleFutureWeatherEntry 中没有 [date,temp] 字段

[英]The columns returned by the query does not have the fields [date,temp] in db.unitlocalized.future.MetricSimpleFutureWeatherEntry

I have tesktask to create a weather app that show weather in users city be GeoLocation.我有 tesktask 创建一个天气应用程序,显示用户所在城市的天气是 GeoLocation。

I use stack of technologies: Dagger,Room, Retrofit,Coroutines.我使用技术堆栈:Dagger、Room、Retrofit、Coroutines。

I have error in dao class.我在 dao class 中有错误。

I create db, because, I want that my should remember state of weather when I want to search city(Not realized yet)我创建数据库,因为,我希望在我想搜索城市时记住天气的 state(尚未实现)

Idk how to fix it, so hope you'll help me. Idk如何修复它,所以希望你能帮助我。

package di
import Repository.ForecastRepositoryImpl
import android.content.Context
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.room.Room
import com.google.android.gms.location.FusedLocationProviderClient
import const.URL_CURRENT
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import db.CurrentWeatherDao
import db.ForecastDb
import db.FutureWeatherDao
import locationprovider.LocationProvider
import locationprovider.LocationProviderImpl
import okhttp3.OkHttpClient
import retrofit.*
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import viewmodel.WeatherForeCastViewModels.FactoryCurrentVM
import viewmodel.WeatherForeCastViewModels.ViewmodelFutureWeather.FutureListViewModelFactory
import javax.inject.Singleton



@Module
@InstallIn(SingletonComponent::class)
object WeatherModule {

@Provides
@Singleton
fun providedaocurrent(appdatabase:ForecastDb): CurrentWeatherDao {
return appdatabase.currentWeatherDao()
}
@RequiresApi(Build.VERSION_CODES.M)

    @Provides
    @Singleton
    fun providesOkHttpClient(connectivityInterceptorImpl:
                             ConnectivityInterceptorImpl)  =
OkHttpClient
    .Builder()
    .addInterceptor(connectivityInterceptorImpl)
    .build()

    @Provides
    @Singleton
    fun provideRetrofit(okHttpClient: OkHttpClient)  = Retrofit.Builder()
        .addConverterFactory(GsonConverterFactory.create())
        .baseUrl(URL_CURRENT)
        .client(okHttpClient)
        .build()

    @Provides
    @Singleton
    fun provideWeatherApiService(retrofit: Retrofit)  =
        retrofit.create(WeatherServiceAPI::class.java)

    @Provides
    @Singleton
  fun provideweathernetworkdatasource
                (weatherNetworkDataSource: WeatherNetworkDataSource):
            WeatherNetworkDataSource{
return weatherNetworkDataSource
  }

@Provides
@Singleton
fun providerepository(repositoryImpl: ForecastRepositoryImpl):
        ForecastRepositoryImpl {
    return repositoryImpl
}
@Provides
@Singleton
fun providevm(vm:FactoryCurrentVM):FactoryCurrentVM{
return  vm

}
@Provides
@Singleton
fun providelocationprovider(locationProviderImpl: LocationProviderImpl):
        LocationProvider{
    return locationProviderImpl
}
    @Provides
    @Singleton
    fun provideforecastdb(@ApplicationContext appContext:Context):
            ForecastDb{
        return Room.databaseBuilder(
            appContext,
            ForecastDb::class.java,
            "forecast.db"
        ).build()
    }

    @Provides
    @Singleton
    fun providefusedlocationproviderclient(fusedLocationProviderClient:
                                           FusedLocationProviderClient):
            FusedLocationProviderClient{
        return fusedLocationProviderClient
    }

    @Provides
    @Singleton
    fun providefutureweatherdao(@ApplicationContext appdb:ForecastDb):
            FutureWeatherDao {
        return appdb.futureweatherdao()

    }

    @Provides
    @Singleton
    fun providevmfactoryfuture(vm:FutureListViewModelFactory):FutureListViewModelFactory{
        return vm
    }
}

package db
import android.content.Context
import androidx.room.*
import db.entities.Current
import db.entities.FutureWeatherEntry
import db.entities.WeatherLocation


@Database(entities = [Current::class,WeatherLocation::class,FutureWeatherEntry::class], version = 1)
@TypeConverters(LocaleDateConverter::class)
abstract class ForecastDb : RoomDatabase() {
    abstract fun futureweatherdao():FutureWeatherDao
    abstract fun currentWeatherDao():CurrentWeatherDao
abstract fun weatherLocationDao():WeatherLocationDao
    companion object{
         @Volatile private var instance:ForecastDb? = null
        private val lock=  Any()
        operator fun invoke(context: Context) = instance ?: synchronized(lock){
            instance ?: builddb(context)
        }
        private fun builddb(context: Context)=
            Room.databaseBuilder(context.applicationContext,RoomDatabase::class.java,"forecast.db").build()
        }
    }

package db

import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import db.entities.FutureWeatherEntry
import db.unitlocalized.future.MetricSimpleFutureWeatherEntry
import java.time.LocalDate


@Dao
interface FutureWeatherDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insert(futureweatherEntries:List<FutureWeatherEntry>) 

    @Query("select * from future_weather where date >=:startDate")
    fun getsimpleweatherforecastmetric(startDate: LocalDate,) :
            LiveData<List<MetricSimpleFutureWeatherEntry>>  // error on this line


    @Query("select * from future_weather where date >=:startDate")
fun countfutureweather(startDate: LocalDate):Int

@Query("delete   from future_weather where date < :firstDateToKeep")
fun deleteOldEntries(firstDateToKeep:LocalDate)
 }

@Dao
interface CurrentWeatherDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE )
    fun upsert(weather: Current)

    @Query("select * from current_weather where id = $Current_Weather_id and isDay =:date")
    fun getWeatherMetric(date:String) : LiveData<MetricCurrentWeather> // error here

}

const val Current_Weather_id = 0
@Entity(tableName = "current_weather")
data class Current(
    val location:String,
    val cloud: Int,
    @Embedded(prefix = "condition_")
    val condition: Condition,
    @SerializedName("feelslike_c")
    val feelslikeC: Double,
    @SerializedName("feelslike_f")
    val feelslikeF: Double,
    @SerializedName("gust_kph")
    val gustKph: Double,
    @SerializedName("gust_mph")
    val gustMph: Double,
    val humidity: Int,
    @SerializedName("is_day")
    val isDay: Int,
    @SerializedName("last_updated")
    val lastUpdated: String,
    @SerializedName("last_updated_epoch")
    val lastUpdatedEpoch: Int,
    @SerializedName("precip_in")
    val precipIn: Double,
    @SerializedName("precip_mm")
    val precipMm: Double,
    @SerializedName("pressure_in")
    val pressureIn: Double,
    @SerializedName("pressure_mb")
    val pressureMb: Double,
    @SerializedName("temp_c")
    val tempC: Double,
    @SerializedName("temp_f")
    val tempF: Double,
    val uv: Double,
    @SerializedName("vis_km")
    val visKm: Double,
    @SerializedName("vis_miles")
    val visMiles: Double,
    @SerializedName("wind_degree")
    val windDegree: Int,
    @SerializedName("wind_dir")
    val windDir: String,
    @SerializedName("wind_kph")
    val windKph: Double,
    @SerializedName("wind_mph")
    val windMph: Double
) {
    @PrimaryKey
    var id : Int = Current_Weather_id
}

@Entity(tableName = "future_weather", indices = [Index(value = ["date"], unique = true )])
data class FutureWeatherEntry(
    @PrimaryKey(autoGenerate = false)
    val id: Int? = null,
    val date: String,
    @Embedded
    val day: Day
)

data class CurrentWeatherResponse(
    @SerializedName("current")
    val current: Current,
    val location: WeatherLocation
)

data class Day(
    val avghumidity: Double,
    @SerializedName("avgtemp_c")
    val avgtempC: Double,
    @SerializedName("avgtemp_f")
    val avgtempF: Double,
    @SerializedName("avgvis_km")
    val avgvisKm: Double,
    @SerializedName("avgvis_miles")
    val avgvisMiles: Double,
    @Embedded(prefix = "condition_")
    val condition: Condition,
    @SerializedName("daily_chance_of_rain")
    val dailyChanceOfRain: Int,
    @SerializedName("daily_chance_of_snow")
    val dailyChanceOfSnow: Int,
    @SerializedName("daily_will_it_rain")
    val dailyWillItRain: Int,
    @SerializedName("daily_will_it_snow")
    val dailyWillItSnow: Int,
    @SerializedName("maxtemp_c")
    val maxtempC: Double,
    @SerializedName("maxtemp_f")
    val maxtempF: Double,
    @SerializedName("maxwind_kph")
    val maxwindKph: Double,
    @SerializedName("maxwind_mph")
    val maxwindMph: Double,
    @SerializedName("mintemp_c")
    val mintempC: Double,
    @SerializedName("mintemp_f")
    val mintempF: Double,
    @SerializedName("totalprecip_in")
    val totalprecipIn: Double,
    @SerializedName("totalprecip_mm")
    val totalprecipMm: Double,
    @SerializedName("totalsnow_cm")
    val totalsnowCm: Double,
    val uv: Double
)

const val weather_location_id = 0
@Entity(tableName = "weather_location")
data class WeatherLocation(
    val country: String,
    val lat: Double,
    val localtime: String,
    @SerializedName("localtime_epoch")
    val localtimeEpoch: Long,
    val lon: Double,
    val name: String,
    val region: String,
    @SerializedName("tz_id")
    val tzId: String
    ){
    @PrimaryKey(autoGenerate = false)
    var id : Int= weather_location_id

    val zonedDateTime:ZonedDateTime
    @RequiresApi(Build.VERSION_CODES.O)
    get() {
        val instant = Instant.ofEpochSecond(localtimeEpoch)
        val zoneId = ZoneId.of(tzId)
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            ZonedDateTime.ofInstant(instant,zoneId)
        } else {
            TODO("VERSION.SDK_INT < O")
        }
    }
}

You are trying to retrieve a MetricCurrentWeather object which requires, according to Room, values for fields date and temp from output columns so named.您正在尝试检索 MetricCurrentWeather object,根据 Room 的说法,它需要来自如此命名的 output 列的字段datetemp的值。

As it stands the query就目前的查询

@Query("select * from current_weather where id = $Current_Weather_id and isDay =:date")
fun getWeatherMetric(date:String) : LiveData<MetricCurrentWeather> // error here

Will extract data that would have the fields sufficient to create a Current object. (ie the Current aka the current_weather table has columns and thus fields avgtemp_c , avgtemp_f and so on).将提取具有足以创建Current object 的字段的数据。(即 Current 又名 current_weather 表具有列,因此具有avgtemp_cavgtemp_f等字段)。

So you could use:-所以你可以使用:-

@Query("select * from current_weather where id = $Current_Weather_id and isDay =:date")
fun getWeatherMetric(date:String) : LiveData<Current>

If you need MetricCurrentWeather to be returned, then you need to alter the query to output the additional columns date and temp with values that are suitable for how they are defined.如果您需要返回MetricCurrentWeather ,则需要将查询更改为 output 附加列 date 和 temp,并使用适合它们定义方式的值。

You could use你可以使用

@Query("select *, 0 AS date, 0 AS temp  from current_weather where id = $Current_Weather_id and isDay =:date")
fun getWeatherMetric(date:String) : LiveData<MetricCurrentWeather>

this would add the two additional columns to the output. However, 0 for both date and temp could be useless and perhaps damaging.这会将两个额外的列添加到 output。但是,日期和温度都为 0 可能是无用的,甚至可能是有害的。

You need to understand what values the date and temp field of the MetricCurrentWeather should hold and how those values should be obtained.您需要了解 MetricCurrentWeather 的日期和临时字段应包含哪些值以及应如何获取这些值。

eg it could be that the last_updated is the date and that temp_c the temp (both fields in the Current object and thus columns in the output) in which case the query could be:-例如,可能是 last_updated 是日期,而 temp_c 是临时(Current object 中的两个字段,因此是输出中的列),在这种情况下,查询可能是:-

 @Query("select *, last_updated AS date, temp_c AS temp  from current_weather where id = $Current_Weather_id and isDay =:date")
 fun getWeatherMetric(date:String) : LiveData<MetricCurrentWeather>
  • That is the output will be all the columns of the current_weather table (* representing all columns) plus two additional columns即 output 将是 current_weather 表的所有列(* 代表所有列)加上另外两个列
    • date (AS date names the column to the required name) which will be the value of the last_updated column, and date (AS date 将列命名为所需的名称)这将是 last_updated 列的值,并且
    • temp (AS temp names the new column to the required name)) which will be the value of the temp_c column. temp (AS temp 将新列命名为所需的名称))这将是 temp_c 列的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM