Skip to main content

快速入门

Obase推荐使用CodeFirst进行项目开发,让我们可以专注于业务模型,而将数据库的设计和管理交给Obase。这意味着,我们不需要直接考虑数据表的设计,而应该专注于业务需求和对象关系映射。Obase底层会根据我们的业务模型自动生成相应的数据库表结构,以支持我们的业务需求。因此,在Obase的帮助下,我们可以更加专注于业务逻辑的开发,而不用过多地考虑数据库方面的问题。

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

public class Student {
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}

安装Obase

安装Obase,如果我们使用Mysql,我们就还需要安装Obase.Providers.MySql

 dotnet add Obase
dotnet add Obase.Providers.MySql

对象上下文配置提供程序

接下来,您可以开始使用Obase了。为了更好地使用Obase,我们需要创建一个新的类(称为对象上下文配置提供程序),并让它继承自MySqlContextConfigProvider。

提示

Obase.Providers.MySql包提供了MySqlContextConfigProvider服务,用于配置MySQL数据库连接。Obase提供了多种数据类型的SqlContextConfigProvider,详见“使用.NET安装”一章中的Packages章节。

/// <summary>
/// 特定于MySql的对象上下文配置提供程序
/// </summary>
public class MySqlContextConfiger : MySqlContextConfigProvider
{
/// <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>
protected override bool EnableStructMapping => true;

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

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

  • ConnectionString,这一属性访问器指定了使用的连接字符串,这里指定一般意义上的连接字符串即可,不同的驱动连接字符串格式不一样,注意示例中的数据库账号密码并非真正的账号密码,读者需要自行定义。
  • CreateModel(ModelBuilder modelBuilder)方法,这一方法指定了如何定义对象上下文中的对象数据模型,这里我们只有一个Student类,我们在这个类的CreateModel方法中将Student注册为实体型,之后还指定了实体型的主键(Id)和主键是不自增的。
提示

在这里,我们引入了一个新的概念——实体型。实体型是实体类型的简称,它在许多ORM(对象关系映射)框架中都有明确的定义。在此,我们将业务系统中对实际事物的抽象类称为实体型。例如,Student就是一个实体型。

在重新实现上述两个属性访问器和一个方法之后,我们就成功创建了一个最简单的上下文配置提供者。

对象上下文

接下来,我们可以编写一个最简单的对象上下文。

/// <summary>
/// 对象上下文
/// </summary>
public class DbContext : ObjectContext<MySqlContextConfiger>
{
/// <summary>
/// Student对象集合
/// </summary>
public ObjectSet<Student> Students { get; set; }
}

这个对象上下文包含一个ObjectSet<T>,被称为数据集合,用于提供新增、删除、查询对象的方法入口。

迁移

程序运行中Obase会检查EnableStructMapping参数,以此条件判断是否对比实体与数据库结构之间的变化,达到自动迁移的目的。

/// <summary>
/// 特定于MySql的对象上下文配置提供程序
/// </summary>
public class MySqlContextConfiger : MySqlContextConfigProvider
{
/// <summary>
/// 自动生成表结构
/// </summary>
protected override bool EnableStructMapping => true;

}

使用对象上下文操作

插入

创建对象和我们之前普通的创建对象几乎一致,只要使用Attach方法讲对象附加在上下文中并保存即可。

//构造对象
var model = new Student
{
Age=18,
Id = 1,
Name = @"Obase"
};
//构造上下文
var context = new DbContext();
//附加在上下文内
context.Students.Attach(model);
//保存
context.SaveChanges();

查询

查询对象只需对上下文中的对象集合进行筛选即可。ObjectSet(对象集合)支持大多数LINQ扩展方法,这一点将在后续的访问存储层部分详细介绍。

//构造上下文
var context = new DbContext();
//查询当前所有持久化的内容
var list = context.Studens.ToList();

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

直接调用ToList()或者ToArray()等方法就可以查询当前所有持久化的对象列表。

更新

对已经持久化的对象我们需要将其查询出来后才能修改。

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

查询出对象后,修改保存即可。

删除

要删除对象首先要查询出需要删除的对象,然后再从对象集合内移除此对象。 对已经持久化的对象我们需要将其查询出来后才能修改。

//构造上下文
var context = new DbContext();
//查询第一个对象
var first = context.Students.FirstOrDefault();
//移除对象
if (first != null)
context.Students.Remove(first);
//保存修改
context.SaveChanges();

使用ObaseGo

ObaseGo大大简化了对象上下文的创建过程,以前我们需要显式地创建一个新的对象上下文,现在只需调用ObaseGo.SetDefault<GoContext>()方法。此方法需要传入一个对象上下文类型,且在整个应用程序生命周期中只能调用一次。通过这个方法,我们可以设置应用程序域内的默认对象上下文类型。一旦设置完成,ObaseGo的后续操作都将基于这个设置的上下文进行。

 //设置默认类型
ObaseGo.SetDefault<GoContext>();

插入

//构造对象
var model = new Student
{
Age=18,
Id = 1,
Name = @"Obase"
};
ObaseGo.SaveNew(model);

查询

//查询当前所有持久化的内容
var list = ObaseGo.ObjectContext.CreateSet<Student>().ToList();

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

更新

ObaseGo.SetAttributes<Students>(
new[] { new KeyValuePair<string, object>("DateTime", DateTime.Now.AddMinutes(1)) },
p => p.IntNumber == 21
);

查询出对象后,修改保存即可。

删除

ObaseGo.Delete<Students>(p => p.IntNumber == 20);

对持久化就地修改

Obase还提供了几个就地修改方法,这些方法会直接修改持久化对象,不会进行相关的关联修改行为。这些方法调用后可直接生效,无需保存。关于关联的内容,将在后续的新手进阶中介绍。

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

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

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

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

//直接修改对象集合中所有符合Id == 1的对象 将Age修改为18
var affectCount = context.Students.SetAttributes(new[] { new KeyValuePair<string, object>("Age", 18) },
p => p.Id == 1);

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

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

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

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

无对象集快速CURD

如果对象上下文不存在对象集,我们可以使用CreateSet来进行CRUD操作,以优化操作过程。

/// <summary>
/// 对象上下文
/// </summary>
public class DbContext : ObjectContext<MySqlContextConfiger>
{
/// <summary>
/// Student对象集合
/// </summary>
public ObjectSet<Student> Students { get; set; }
}
public class Car
{
public string Id { get; set; }
public string Make { get; set; }
public string Model { get; set; }
}

使用对象集的用法:

var context = new DbContext();
var list = context.Studens.ToList();

使用CreateSet无需在对象上下文定义属性,示例:

//构造上下文
var context = new DbContext();
//查询当前所有持久化的内容
var list = context.CreateSet<Car>.ToList();
context.CreateSet<Car>().Attach(new Car());
context.CreateSet<Car>().Delete(p => p.Id > 0);