结合使用 ADO.NET 和 AndroidUsing ADO.NET with Android

02/08/2018

本文内容

Xamarin 内置了对适用于 Android 的 SQLite 数据库的支持,可以使用熟悉的类似 ADO.NET 的语法公开。Xamarin has built-in support for the SQLite database that is available on Android and can be exposed using familiar ADO.NET-like syntax. 使用这些 Api 需要编写由 SQLite 处理的 SQL 语句,如 CREATE TABLE、INSERT 和 SELECT 语句。Using these APIs requires you to write SQL statements that are processed by SQLite, such as CREATE TABLE, INSERT and SELECT statements.

程序集引用Assembly References

若要通过 ADO.NET 使用访问 SQLite,你必须将 System.Data 和 Mono.Data.Sqlite 引用添加到 Android 项目,如下所示:To use access SQLite via ADO.NET you must add System.Data and Mono.Data.Sqlite references to your Android project, as shown here:

右键单击 "引用" > 编辑引用 ... ",然后单击以选择所需的程序集。Right-click References > Edit References... then click to select the required assemblies.

关于 Mono. SqliteAbout Mono.Data.Sqlite

我们将使用 Mono.Data.Sqlite.SqliteConnection 类创建一个空数据库文件,然后实例化可用于对数据库执行 SQL 指令的 SqliteCommand 对象。We will use the Mono.Data.Sqlite.SqliteConnection class to create a blank database file and then to instantiate SqliteCommand objects that we can use to execute SQL instructions against the database.

创建空白数据库– 调用具有有效(即可写)文件路径的 CreateFile 方法。Creating a Blank Database – Call the CreateFile method with a valid (i.e. writeable) file path. 在调用此方法之前,应检查文件是否已存在,否则将在旧文件的顶部创建新的(空白)数据库,并将丢失旧文件中的数据。You should check whether the file already exists before calling this method, otherwise a new (blank) database will be created over the top of the old one, and the data in the old file will be lost.

Mono.Data.Sqlite.SqliteConnection.CreateFile (dbPath); dbPath 变量应按照本文档前面讨论的规则确定。Mono.Data.Sqlite.SqliteConnection.CreateFile (dbPath); The dbPath variable should be determined according the rules discussed earlier in this document.

创建数据库连接– 创建 SQLite 数据库文件后,可以创建连接对象来访问数据。Creating a Database Connection – After the SQLite database file has been created you can create a connection object to access the data. 连接是使用采用 Data Source=file_path形式的连接字符串构造的,如下所示:The connection is constructed with a connection string which takes the form of Data Source=file_path, as shown here:

var connection = new SqliteConnection ("Data Source=" + dbPath);

connection.Open();

// do stuff

connection.Close();

如前所述,连接永远不能在不同的线程之间重复使用。 如果有疑问,请根据需要创建连接并在完成后关闭它;但请注意,此操作的执行频率要高于所需的频率。If in doubt, create the connection as required and close it when you're done; but be mindful of doing this more often than required too.

创建和执行数据库命令– 一旦建立连接,就可以对其执行任意 SQL 命令。Creating and Executing a Database Command – Once we have a connection we can execute arbitrary SQL commands against it. 下面的代码显示正在执行的 CREATE TABLE 语句。The code below shows a CREATE TABLE statement being executed.

using (var command = connection.CreateCommand ()) {

command.CommandText = "CREATE TABLE [Items] ([_id] int, [Symbol] ntext, [Name] ntext);";

var rowcount = command.ExecuteNonQuery ();

}

当直接针对数据库执行 SQL 时,应采取正常的预防措施来避免发出无效请求,例如,尝试创建已存在的表。When executing SQL directly against the database you should take the normal precautions not to make invalid requests, such as attempting to create a table that already exists. 跟踪数据库的结构,以便不会导致 SqliteException 如SQLite 错误表 [Items] 已存在。Keep track of the structure of your database so that you don't cause a SqliteException such as SQLite error table [Items] already exists.

基本数据访问Basic Data Access

在 Android 上运行时,此文档的DataAccess_Basic示例代码如下所示:The DataAccess_Basic sample code for this document looks like this when running on Android:

下面的代码演示了如何执行简单的 SQLite 操作并在应用程序的主窗口中以文本形式显示结果。The code below illustrates how to perform simple SQLite operations and shows the results in as text in the application's main window.

需要包含以下命名空间:You'll need to include these namespaces:

using System;

using System.IO;

using Mono.Data.Sqlite;

下面的代码示例演示了整个数据库交互:The following code sample shows an entire database interaction:

创建数据库文件Creating the database file

插入一些数据Inserting some data

查询数据Querying the data

这些操作通常出现在代码中的多个位置,例如,你可以在应用程序第一次启动时创建数据库文件和表,并在应用中的各个屏幕上执行数据读写操作。These operations would typically appear in multiple places throughout your code, for example you may create the database file and tables when your application first starts and perform data reads and writes in individual screens in your app. 在下面的示例中,已将此示例中的一个方法分组为一个方法:In the example below have been grouped into a single method for this example:

public static SqliteConnection connection;

public static string DoSomeDataAccess ()

{

// determine the path for the database file

string dbPath = Path.Combine (

Environment.GetFolderPath (Environment.SpecialFolder.Personal),

"adodemo.db3");

bool exists = File.Exists (dbPath);

if (!exists) {

Console.WriteLine("Creating database");

// Need to create the database before seeding it with some data

Mono.Data.Sqlite.SqliteConnection.CreateFile (dbPath);

connection = new SqliteConnection ("Data Source=" + dbPath);

var commands = new[] {

"CREATE TABLE [Items] (_id ntext, Symbol ntext);",

"INSERT INTO [Items] ([_id], [Symbol]) VALUES ('1', 'AAPL')",

"INSERT INTO [Items] ([_id], [Symbol]) VALUES ('2', 'GOOG')",

"INSERT INTO [Items] ([_id], [Symbol]) VALUES ('3', 'MSFT')"

};

// Open the database connection and create table with data

connection.Open ();

foreach (var command in commands) {

using (var c = connection.CreateCommand ()) {

c.CommandText = command;

var rowcount = c.ExecuteNonQuery ();

Console.WriteLine("\tExecuted " + command);

}

}

} else {

Console.WriteLine("Database already exists");

// Open connection to existing database file

connection = new SqliteConnection ("Data Source=" + dbPath);

connection.Open ();

}

// query the database to prove data was inserted!

using (var contents = connection.CreateCommand ()) {

contents.CommandText = "SELECT [_id], [Symbol] from [Items]";

var r = contents.ExecuteReader ();

Console.WriteLine("Reading data");

while (r.Read ())

Console.WriteLine("\tKey={0}; Value={1}",

r ["_id"].ToString (),

r ["Symbol"].ToString ());

}

connection.Close ();

}

更复杂的查询More Complex Queries

由于 SQLite 允许对数据运行任意 SQL 命令,因此你可以执行所需的任何 CREATE、INSERT、UPDATE、DELETE或 SELECT 语句。Because SQLite allows arbitrary SQL commands to be run against the data, you can perform whatever CREATE, INSERT, UPDATE, DELETE, or SELECT statements you like. 可以在 SQLite 网站上阅读 SQLite 支持的 SQL 命令。You can read about the SQL commands supported by SQLite at the SQLite website. 使用 SqliteCommand 对象上三种方法之一来运行 SQL 语句:The SQL statements are run using one of three methods on an SqliteCommand object:

ExecuteNonQuery – 通常用于表创建或数据插入。ExecuteNonQuery – Typically used for table creation or data insertion. 某些运算的返回值为受影响的行数,否则为-1。The return value for some operations is the number of rows affected, otherwise it's -1.

当行集合应作为 SqlDataReader返回时,使用ExecuteReader –。ExecuteReader – Used when a collection of rows should be returned as a SqlDataReader.

ExecuteScalar – 检索单个值(例如聚合)。ExecuteScalar – Retrieves a single value (for example an aggregate).

EXECUTENONQUERYEXECUTENONQUERY

INSERT、UPDATE和 DELETE 语句将返回受影响的行数。INSERT, UPDATE, and DELETE statements will return the number of rows affected. 所有其他 SQL 语句将返回-1。All other SQL statements will return -1.

using (var c = connection.CreateCommand ()) {

c.CommandText = "INSERT INTO [Items] ([_id], [Symbol]) VALUES ('1', 'APPL')";

var rowcount = c.ExecuteNonQuery (); // rowcount will be 1

}

EXECUTEREADEREXECUTEREADER

下面的方法演示了 SELECT 语句中的 WHERE 子句。The following method shows a WHERE clause in the SELECT statement.

由于代码正在编写完整的 SQL 语句,因此它必须小心地转义保留字符,如引号("),如字符串。Because the code is crafting a complete SQL statement it must take care to escape reserved characters such as the quote (') around strings.

public static string MoreComplexQuery ()

{

var output = "";

output += "\nComplex query example: ";

string dbPath = Path.Combine (

Environment.GetFolderPath (Environment.SpecialFolder.Personal), "ormdemo.db3");

connection = new SqliteConnection ("Data Source=" + dbPath);

connection.Open ();

using (var contents = connection.CreateCommand ()) {

contents.CommandText = "SELECT * FROM [Items] WHERE Symbol = 'MSFT'";

var r = contents.ExecuteReader ();

output += "\nReading data";

while (r.Read ())

output += String.Format ("\n\tKey={0}; Value={1}",

r ["_id"].ToString (),

r ["Symbol"].ToString ());

}

connection.Close ();

return output;

}

ExecuteReader 方法返回 SqliteDataReader 对象。The ExecuteReader method returns a SqliteDataReader object. 除了示例中所示的 Read 方法以外,其他有用的属性包括:In addition to the Read method shown in the example, other useful properties include:

RowsAffected – 受查询影响的行的计数。RowsAffected – Count of the rows affected by the query.

HasRows – 是否返回了任何行。HasRows – Whether any rows were returned.

EXECUTESCALAREXECUTESCALAR

对于返回单个值(例如聚合)的 SELECT 语句,请使用此函数。Use this for SELECT statements that return a single value (such as an aggregate).

using (var contents = connection.CreateCommand ()) {

contents.CommandText = "SELECT COUNT(*) FROM [Items] WHERE Symbol <> 'MSFT'";

var i = contents.ExecuteScalar ();

}

ExecuteScalar 方法的返回类型 object – 应根据数据库查询强制转换结果。The ExecuteScalar method's return type is object – you should cast the result depending on the database query. 结果可能是来自 COUNT 查询的整数,或是 SELECT 查询的单个列中的字符串。The result could be an integer from a COUNT query or a string from a single column SELECT query. 请注意,这不同于其他 Execute 方法,这些方法返回读取器对象或受影响的行数的计数。Note that this is different to other Execute methods that return a reader object or a count of the number of rows affected.

相关链接Related Links

mono for android mysql_结合使用 ADO.NET 和 Android相关推荐

  1. Android监听左右滑删除通知,Android 滑动监听RecyclerView线性流+左右划删除+上下移动...

    废话不多说了,直接给大家贴代码了.具体代码如下所示: xmlns:tools="http://schemas.android.com/tools" android:layout_w ...

  2. ios android安全性分析,Android与iOS的对比分析及Android安全技术的设计与实现

    摘要: 近年来科技的发展和进步极大的推动了智能手机的飞速发展,手机功能的日益强大使人们对其依赖度显著上升.作为与人们生活密不可分通讯工具,手机安全的重要性不言而喻.现如今,随着手机网络的迅猛发展和形形 ...

  3. android wear无法启用,android-wear – 无法创建Android虚拟设备,“没有为此目标安装系统映像”...

    为了创建一个Android穿戴式模拟器,你需要按照下面的说明, 1.如果您的Android SDK工具版本低于22.6,您必须更新 2.在Android 4.4.2下,选择Android Wear A ...

  4. android 监听物理返回键,Android应用开发之react-native 监听Android物理返回键

    本文将带你了解Android应用开发之react-native 监听Android物理返回键,希望本文对大家学Android有所帮助. 1. componentWillMount(){         ...

  5. android中仿qq最新版抽屉,Android实现3种侧滑效果(仿qq侧滑、抽屉侧滑、普通侧滑)...

    自己实现了一下侧滑的三种方式(注释都写代码里了) 本文Demo下载地址:Andriod侧滑 本文实现所需框架:nineoldandroids下载地址:nineoldandroids 1.普通侧滑: 主 ...

  6. android 固定底部导航,如何设置android底部导航栏位置固定在android

    请帮我设置底部导航栏位置固定在底部, ,因为我在输入editText字段时遇到问题,底部导航栏向上移动并覆盖其他领域如何设置android底部导航栏位置固定在android 代码: xmlns:and ...

  7. android开发之Intent.setFlags()_让Android点击通知栏信息后返回正在运行的程序

    android开发之Intent.setFlags()_让Android点击通知栏信息后返回正在运行的程序   在应用里使用了后台服务,并且在通知栏推送了消息,希望点击这个消息回到activity, ...

  8. Android多个权限多次请求,android – 获取W / Activity:一次只能请求一组权限

    我制作了一个应用程序,它有摄像头和GPS的请求,但是当我执行时,我会多次收到此警告,而不到1秒. W/Activity: Can reqeust only one set of permissions ...

  9. android 启动白屏_为什么说Android 架构的未来是 MVVM?

    据<第45次中国互联网络发展状况统计报告>,2019年市场上监测到的APP数量比2018年减少85万款- 这两年,很多朋友都会有这样的疑惑: "现在Android的坑还值不值得入 ...

最新文章

  1. DPDK — 扩展私有函数库
  2. 【Python基础】弄懂这几个问题,拿下 Python 生成器!
  3. python scoket、SocketServer简单实现文件上传下载
  4. 弱投影模型_通过投影增强数据模型
  5. 【2012百度之星资格赛】F:百科蝌蚪团
  6. IEEE Signal Processing Letters
  7. php检查是否支持openssl,swoole环境是否支持openssl
  8. 【JAVA面试题整理】框架之Shiro
  9. 推荐可永久保存文件的免费网络硬盘
  10. 通过减小Bootstrapping Error Reduction来进行离线RL学习
  11. (四)Loadrunner 代理录制
  12. h264解码延迟优化_h264编解码末尾丢帧问题原因和解决
  13. 【预防流感】冬春之交推荐吃香菜
  14. Unity+Kinect 开发脚本介绍
  15. 结合可变形注意力的视觉Transformer
  16. vue 页脚_前端必懂之Sticky Footer(粘性页脚)
  17. qq音乐html5测试性格,根据你的听歌习惯测试你的性格
  18. 【其他】【RQNOJ】吉祥数
  19. 云计算简介:云计算定义、云计算优势、云计算分类、云计算历史
  20. 一本通1603绿色通道

热门文章

  1. Python中的yield生成器的简单介绍
  2. LeetCode 90.子集 II 中等难度
  3. 这家公司向苹果索赔百亿!一场鏖战八年的专利之争仍未结束
  4. Visual C++语言编程开发详解(孙鑫老师)
  5. Windows程序设计之创建窗口示例
  6. 人工智能伦理体系:基础架构与关键问题
  7. 中国18岁美女机器人:出得厅堂,下得厨房,还要什么女朋友!
  8. QQ使用了什么通讯协议?为什么要这样做?为什么采用 UDP 协议,而不采用 TCP 协议实现?
  9. send(),recv()函数详解
  10. GetOverlappedResult函数详细解答