在 iOS 应用中使用数据

DataAccess_Adv 示例显示了一个工作应用程序,它支持用户输入和 CRUD (创建、读取、更新和删除)数据库功能。 该应用程序包括两个屏幕:列表和数据输入窗体。 所有数据访问代码在 iOS 和 Android 中均可重用,无需修改。

添加一些数据后,应用程序屏幕在 iOS 上的外观如下所示:

iOS sample list

iOS sample detail

iOS 项目如下所示 - 本部分中显示的代码包含在 Orm 目录中:

iOS project tree

iOS 中 ViewControllers 的本机 UI 代码不再本文档范围内。 有关 UI 控件的详细信息,请参阅 iOS 使用表和单元格指南。

读取

示例中存在几个读取操作:

  • 读取列表
  • 读取单个记录

StockDatabase 类中的两种方法是:

public IEnumerable<Stock> GetStocks ()
{
    lock (locker) {
        return (from i in Table<Stock> () select i).ToList ();
    }
}
public Stock GetStock (int id)
{
    lock (locker) {
        return Table<Stock>().FirstOrDefault(x => x.Id == id);
    }
}

iOS 将数据以不同方式呈现为 UITableView

创建和更新

为了简化应用程序代码,提供了一个保存方法来执行插入或更新,具体取决于是否已设置 PrimaryKey。 由于该 Id 属性使用 [PrimaryKey] 属性进行标记,因此不应在代码中设置该属性。 此方法将检测之前是否已保存值(通过检查主键属性)并相应地插入或更新对象:

public int SaveStock (Stock item)
{
    lock (locker) {
        if (item.Id != 0) {
            Update (item);
            return item.Id;
    } else {
            return Insert (item);
        }
    }
}

实际应用程序通常需要一些验证(例如必填字段、最小长度或其他业务规则)。 良好的跨平台应用程序可在共享代码中尽可能多地实现验证逻辑,从而根据平台的功能将验证错误传回 UI 以进行显示。

删除

Insert 方法和 Update 方法不同,该 Delete<T> 方法只能接受主键值而不是完整的 Stock 对象。 在此示例中,Stock 对象将传递到方法中,但仅向 Delete<T> 方法传递 Id 属性。

public int DeleteStock(Stock stock)
{
    lock (locker) {
        return Delete<Stock> (stock.Id);
    }
}

使用预填充的 SQLite 数据库文件

一些应用程序随已填充数据的数据库一起提供。 在移动应用程序中,可以轻松完成此操作,方法是将现有的 SQLite 数据库文件与应用一起提供,并将其复制到可写目录,然后再访问它。 由于 SQLite 是许多平台上使用的标准文件格式,因此可以使用许多工具创建 SQLite 数据库文件:

  • SQLite Manager Firefox 扩展 - 适用于 Mac 和 Windows,并生成与 iOS 和 Android 兼容的文件。
  • 命令行 - 请参阅 www.sqlite.org/sqlite.html

创建数据库文件以便与应用一起分发时,请注意表和列的命名,以确保它们与代码预期匹配,尤其是在使用预期名称与 C# 类和属性(或关联的自定义属性)相匹配的 SQLite.NET 时。

对于 iOS,请在应用程序中包括 sqlite 文件,并确保使用“生成操作:内容”标记它。 在调用任何数据方法之前,请将代码放置在 FinishedLaunching 中以将文件复制到可写目录。 以下代码将复制名为 data.sqlite 的现有数据库,前提是该数据库尚不存在。

// Copy the database across (if it doesn't exist)
var appdir = NSBundle.MainBundle.ResourcePath;
var seedFile = Path.Combine (appdir, "data.sqlite");
if (!File.Exists (Database.DatabaseFilePath))
{
  File.Copy (seedFile, Database.DatabaseFilePath);
}

完成此操作后执行的任何数据访问代码(无论是 ADO.NET 还是使用 SQLite.NET)都将有权访问预填充的数据。