obase社区Obase开发者QQ群:962698871
obase

欢迎查阅
OBASE帮助文档

本节内容对应的Demo位于Obase.Test.Demo中Obase.Test/QuickStart,Obase.Test.Infrastructure/QuickStart和Obase.Test.Domain内,所使用的数据库表建表脚本(MySql版)位于Obase.Test.Infrastructure内。

我们将以一个简单的类来介绍Obase的主要用法,类的代码如下:

/// <summary>
///     一个类似于JavaBean的失血模型 包含若干常用的数据类型属性访问器
/// </summary>
public class JavaBean
{
    /// <summary>
    ///     int类型数字
    /// </summary>
    public int IntNumber { get; set; }

    /// <summary>
    ///     decimal类型数字
    /// </summary>
    public double DecimalNumber { get; set; }

    /// <summary>
    ///     时间类型
    /// </summary>
    public DateTime DateTime { get; set; }

    /// <summary>
    ///     字符串类型
    /// </summary>
    public string String { get; set; }

    /// <summary>
    ///     布尔值类型
    /// </summary>
    public bool Bool { get; set; }

    /// <summary>
    ///     转换为字符串表示形式
    /// </summary>
    /// <returns></returns>
    public override string ToString()
    {
        return
            $"JavaBeanLikeModel:{{IntNumber-{IntNumber},DecimalNumber-{DecimalNumber},DateTime-\"{DateTime:yyyy-MM-dd HH:mm:ss}\",String-\"{String}\",Bool-\"{Bool}\"}}";
    }
}

这个类内包含几个常见类型的属性访问器:整型,双精度浮点,时间,字符串,布尔值组等。 我们在使用这样的类时,也往往会为它在数据库里建一张同名的表,下面是使用MySql作为数据库的建表语句:

CREATE TABLE `javabeanlikemodel` (
`IntNumber` int(11) DEFAULT NULL,
`DecimalNumber` decimal(10,0) DEFAULT NULL,
`DateTime` datetime DEFAULT NULL,
`String` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
`Bool` tinyint(4) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

接下来就可以开始使用Obase了。

  1. 项目搭建 首先,我们创建一个解决方案Obase.Test.Demo作为演示用,在解决方案中创建两个项目Obase.Test.Domain和Obase.Test.Infastructure。其中TDomain内是演示用的领域模型,之前提到的JavaBean类位于此项目内;Infastructure是引入并继承Obase中某些类的中间层,并需要引用实际的持久化对应的驱动(如MySql.Data,System.Data.SqlClient)等。 最终的引用关系如下: 项目关系 其中Obase为Obase框架本体,Obase.Sql为特定于Sql的存储扩展,同时Obase.Test.Infrastructure还引用了MySql.Data包作为特定于MySql的数据提供程序。
  2. 配置对象上下文(ObjectContext) 在Infrastructure内我们新建一个类(称为对象上下文配置提供程序),继承Obase.Sql.SqlContexConfiger并编写如下代码:
/// <summary>
///     特定于MySql的对象上下文配置提供程序
/// </summary>
public class JavaBeanMySqlContextConfiger : SqlContexConfiger
{
    /// <summary>
    ///     获取特定于数据库服务器(SQL Server、Oracle等)的数据提供程序工厂
    /// </summary>
    protected override DbProviderFactory DbProviderFactory => MySqlClientFactory.Instance;

    /// <summary>
    ///     连接字符串
    /// </summary>
    protected override string ConnectionString => "server=127.0.0.1;database=obaseautotest;uid=XXX;pwd=XXX;pooling=false;CharSet=utf8;port=3306;SslMode=none;";

    /// <summary>
    ///     使用指定的建模器创建对象数据模型。
    /// </summary>
    /// <param name="modelBuilder"></param>
    protected override void CreateModel(ModelBuilder modelBuilder)
    {
        //注册JavaBean模型
        var javabeanConfig = modelBuilder.Entity<JavaBean>();
        //为模型设置主键和主键自增
        javabeanConfig.HasKeyAttribute(p => p.IntNumber).HasKeyIsSelfIncreased(false);
    }
}

这里的JavaBeanMySqlContextConfiger是特定于MySql数据库的上下文配置提供者,主要重写了这几个属性访问器和方法:

  • DbProviderFactory,这一属性访问器指定了使用何种数据库连接器(或称为驱动),这里一般指定为驱动中相应的数据提供程序工厂的Instance属性访问器。
  • ConnectionString,这一属性访问器指定了使用的连接字符串,这里指定一般意义上的连接字符串即可,注意示例中的数据库账号密码并非真正的账号密码,读者需要自行定义。
  • CreateModel(ModelBuilder modelBuilder)方法,这一方法指定了如何定义对象上下文中的对象数据模型,这里我们只有一个JavaBean类,我们在这个类的CreateModel方法中将javabean注册为实体型,之后还指定了实体型的主键(IntNumber)和主键是不自增的。这里提到了一个新的概念:实体型,实体型是实体类型的简称,在诸多的Orm中都有对实体型的定义,在这里我们把业务系统中对事物抽象的类称作实体型,这里的JavaBean就是一个实体型。当然,JavaBean还有其他的属性,但这些属性都较为简单,只有Get和Set方法,所以无需进行配置,Obase会自动对其进行配置。

在重写了以上两个属性访问器和一个方法后,我们就得到了一个最简的上下文配置提供者,类似的我们也可以写出其他几种支持的主流Sql数据库的上下文配置提供者:

/// <summary>
///  特定于SqlServer的对象上下文配置提供程序
/// </summary>
public class JavaBeanSqlServerContextConfiger : SqlContexConfiger
{
    /// <summary>
    ///     获取特定于数据库服务器(SQL Server、Oracle等)的数据提供程序工厂
    /// </summary>
    protected override DbProviderFactory DbProviderFactory => SqlClientFactory.Instance;

    /// <summary>
    ///     连接字符串
    /// </summary>
    protected override string ConnectionString => "Data Source=127.0.0.1;Initial Catalog=obaseautotest;User Id=XXX;Password=XXX;";

    /// <summary>
    ///     使用指定的建模器创建对象数据模型。
    /// </summary>
    /// <param name="modelBuilder"></param>
    protected override void CreateModel(ModelBuilder modelBuilder)
    {
        //注册JavaBean模型
        var javabeanConfig = modelBuilder.Entity<JavaBean>();
        //为模型设置主键和主键自增
        javabeanConfig.HasKeyAttribute(p => p.IntNumber).HasKeyIsSelfIncreased(false);
    }
}
/// <summary>
///    特定于Oracle的对象上下文配置提供程序
/// </summary>
public class JavaBeanOracleContextConfiger : SqlContexConfiger
{
    /// <summary>
    ///     获取特定于数据库服务器(SQL Server、Oracle等)的数据提供程序工厂
    /// </summary>
    protected override DbProviderFactory DbProviderFactory => OracleClientFactory.Instance;

    /// <summary>
    ///     连接字符串
    /// </summary>
    protected override string ConnectionString => "User=XXX; Password=XXX; Host=127.0.0.1; Port=3306; Database=obasetest;";

    /// <summary>
    ///     使用指定的建模器创建对象数据模型。
    /// </summary>
    /// <param name="modelBuilder"></param>
    protected override void CreateModel(ModelBuilder modelBuilder)
    {
        //注册JavaBean模型
        var javabeanConfig = modelBuilder.Entity<JavaBean>();
        //为模型设置主键和主键自增
        javabeanConfig.HasKeyAttribute(p => p.IntNumber).HasKeyIsSelfIncreased(false);
        //在模型中忽略某些属性
        javabeanConfig.Ignore(p => p.Strings);
    }
}
/// <summary>
///    特定于Sqlite的对象上下文配置提供程序
/// </summary>
public class JavaBeanSqliteContextConfiger : SqlContexConfiger
{
    /// <summary>
    ///     获取特定于数据库服务器(SQL Server、Oracle等)的数据提供程序工厂
    /// </summary>
    protected override DbProviderFactory DbProviderFactory => SqliteFactory.Instance;

    /// <summary>
    ///     连接字符串
    /// </summary>
    protected override string ConnectionString => "Data Source={AppData}\\obaseTest.db;Version=3;Pooling=False;Max Pool Size=100;Password=XXX;";

    /// <summary>
    ///     使用指定的建模器创建对象数据模型。
    /// </summary>
    /// <param name="modelBuilder"></param>
    protected override void CreateModel(ModelBuilder modelBuilder)
    {
        //注册JavaBean模型
        var javabeanConfig = modelBuilder.Entity<JavaBean>();
        //为模型设置主键和主键自增
        javabeanConfig.HasKeyAttribute(p => p.IntNumber).HasKeyIsSelfIncreased(false);
        //在模型中忽略某些属性
        javabeanConfig.Ignore(p => p.Strings);
    }
}

同样的,这几个上下文配置提供者的连接字符串中均需要读者自行修改。 在Demo中,我们使用MySql的上下文配置提供者作为示例。 那么,相应的我们可以写出一个最简的对象上下文:

/// <summary>
///     javabean对象上下文
/// </summary>
public class JavaBeanContext : ObjectContext<JavaBeanMySqlContextConfiger>
{
    /// <summary>
    ///     javabean对象集合
    /// </summary>
    public ObjectSet<JavaBean> JavaBeans { get; set; }
}

这个对象上下文内包含一个ObjectSet<>,被称为数据集合,用来提供新增删除查询对象的方法入口。对象上下文要求一个泛型参数,此参数必须是继承自ContextConfigProvider的(此处SqlContexConfiger是继承ContextConfigProvider的)且必须有一个无参的构造函数。 关于对象建模的内容(之前的注册为实体型,为实体型设置主键,忽略某个属性)会在对象系统建模中详细介绍。 数据上下文和数据上下文配置器会在之后的访问存储层部分详细介绍。

  1. 创建对象并使用Obase持久化 创建对象和我们之前普通的创建对象几乎一致,只要将对象附加在上下文中并保存即可。
//构造对象
var model = new JavaBean
{
    Bool = 7 % 2 == 0,
    DateTime = DateTime.Now,
    DecimalNumber = Math.Pow(Math.PI, 4),
    IntNumber = 1,
    String = @"1号字符串"
};
//构造上下文
var context = new JavaBeanContext();
//附加在上下文内
context.JavaBeans.Attach(model);
//保存
context.SaveChanges();
  1. 使用Obase查询持久化的对象 查询对象只要对上下文中的对象集合进行筛选即可,ObjectSet(对象集合)支持大部分的linq扩展方法,这一部分会在之后的访问存储层中详细介绍。
//构造上下文
var context = new JavaBeanContext();
//查询当前所有持久化的内容
var list = context.JavaBeans.ToList();

foreach (var javaBean in list)
{
    Console.WriteLine(javaBean);
}

直接调用ToList()或者ToArray()等方法就可以查询当前所有持久化的对象列表。 5. 修改对象并使用Obase持久化 对已经持久化的对象我们需要将其查询出来后才能修改。

//构造上下文
var context = new JavaBeanContext();
//查询第一个对象
var first = context.JavaBeans.FirstOrDefault();
//修改对象
if (first != null)
    first.DateTime = DateTime.Now.AddMinutes(1);
//保存修改
context.SaveChanges();

查询出对象后,修改保存即可。 6. 删除对象并使用Obase持久化 要删除对象首先要查询出需要删除的对象,然后再从对象集合内移除此对象。 对已经持久化的对象我们需要将其查询出来后才能修改。

//构造上下文
var context = new JavaBeanContext();
//查询第一个对象
var first = context.JavaBeans.FirstOrDefault();
//移除对象
if (first != null)
    context.JavaBeans.Remove(first);
//保存修改
context.SaveChanges();
  1. 使用Obase对持久化就地修改 Obase还提供了几个就地修改方法,这些方法会直接修改持久化对象,并不会进行连带的关联修改等行为,这些方法调用后直接生效,无需进行保存。 关于关联的内容,在之后的新手进阶中会加以介绍。
//构造上下文
var context = new JavaBeanContext();

//直接删除对象集合中所有符合IntNumber == 1的对象
var affectCount = context.JavaBeans.Delete(p => p.IntNumber == 1);

直接删除方法接收一个参数,用于筛选所有符合条件的对象并加以删除,并会返回受到影响的行数。

//构造上下文
var context = new JavaBeanContext();

//直接修改对象集合中所有符合IntNumber == 1的对象 将DateTime修改至当前时间+5分钟
var affectCount = context.JavaBeans.SetAttributes(new[] { new KeyValuePair<string, object>("DateTime", DateTime.Now.AddMinutes(5)) },
    p => p.IntNumber == 1);

直接修改方法(设置新值)接收两个参数,一个是新值键值对集合,这个集合要与持久化中的对应字段相匹配,否则会报错;另一个是筛选条件,这与之前的直接删除方法一致。此方法会返回受到影响的行数,并将指定的字段覆盖为新的值。

//构造上下文
var context = new JavaBeanContext();

//直接修改对象集合中所有符合IntNumber == 1的对象 将DecimalNumber递增1
var affectCount = context.JavaBeans.IncreaseAttributes(new[] { new KeyValuePair<string, object>("DecimalNumber", 1) },
    p => p.IntNumber == 1);

直接修改方法(递增新值)接收两个参数,一个是新值键值对集合,这个集合要与持久化中的对应字段相匹配,否则会报错;另一个是筛选条件,这与之前的直接删除方法一致。此方法会返回受到影响的行数,并将指定的字段以累加的方式设置为新的值,即上方的例子中如果DecimalNumber是2,则调用IncreaseAttributes后会被设置成3。

没有找到您需要的文档?

您还可以通过人工服务在线咨询,服务时间为每天上午9点至下午6点。

If you can't find required answer, get in touch with us online. We provide service from 9:00 to 18:00.

让编程成为一件快乐的事
现在开始