我编写了以下函数来查询我的Xamarin表单应用程序中的SQLite数据库。但是,因为我必须两次调用 .ToList(),所以我对此并不十分自信。这是坏代码吗?任何反馈都将受到高度赞赏。
public static List<string> GetAllLocationIds()
{
try
{
lock (CollisionLock)
{
//TableQuery<TResult> First .ToList() result
//List<string> Second .ToList() result
return Database.Table<Location>().ToList().Select(loc=>loc.LocationId).ToList();
}
}
catch (Exception ex)
{
Insights.Report(ex);
return null;
}
}
执行。直接在Database.Table<Location>()
上选择会导致以下异常。
System.MissingMethodException: Default constructor not found for type
System.String at System.RuntimeType.CreateInstanceMono`
答案 0 :(得分:4)
是的。
在
Database.Table<Location>().ToList()
您正在实现表Location
的所有内容。然后,您只在内存中选择LocationId
。
改为使用:
Database.Table<Location>().Select(loc=>loc.LocationId).ToList();
哪个直接在IQueryable<Location>
上工作,并且只实现LocationId
。假设Table<Location>
为IQueryable<Location>
。
答案 1 :(得分:1)
由于需要默认的无参数构造函数,您无法对string
类型的sqlite-net(-pcl)
类型进行Linq投影。
以下是&#34;最佳方式&#34;模拟&#34; Linq投影&#34;我在考虑移动内存和性能时发现的。
where
过滤器)class Location
{
[PrimaryKey]
public int Column1 { get; set; }
public int Column2 { get; set; }
~~~
public string LocationId { get; set; }
}
现在创建一个新课程,描述您的&#34;投影&#34;在这种情况下,我只需要LocationId
列。
class SimpleList
{
public string LocationId { get; set; }
}
SQLiteConnection.Query<SimpleList>("select LocationId from [Location]")
现在您有一个List<SimpleList>
,如果您确实需要,可以将其转换为List<string>
:
SQLiteConnection.Query<SimpleList>("select LocationId from [Location]").ConvertAll(x => x.LocationId);
值得吗?如果表格中有 大 行数和/或列数,不能使用延迟查询和/或避免Linq投影。 ..恕我直言...使用探查器确认; - )
如果你有几十排吗?也许不是,但即便如此,温度的数量。获得实例化的对象减少了,对我而言,这是移动设备的胜利。