Install FreeSql, OceanBase.ManagedDataAccess, and FreeSql.Provider.OceanBase in OceanBase Oracle mode, and obtain IFreeSql through OceanBaseProvider<TMark>. For the connection string format, see Connection string. For packages and versions, see Package reference and usage instructions.
Installation method
Same as the base driver:
dotnet add package FreeSql
dotnet add package OceanBase.ManagedDataAccess
dotnet add package FreeSql.Provider.OceanBase
Note
Starting from V1.3.0, FreeSql.Provider.OceanBase supports netstandard2.0, net461, net6.0, net7.0, net8.0, net9.0, and net10.0.
Connection string
Use the Oracle-compatible mode format supported by the driver. Replace the placeholders with actual environment values; do not directly copy the literals in the example:
server=<host or IP>;port=<port>;user id=<OceanBase Oracle account>;password=<password>;database=<schema name>;
If the session needs to use the GBK character set, you can append Character Set=gbk (aliases CharSet / CharacterSet):
server=<host or IP>;port=<port>;user id=<OceanBase Oracle account>;password=<password>;database=<schema name>;Character Set=gbk;
Note
user idis an OceanBase Oracle-compatible mode account.- We recommend that you do not omit
database. The metadata capabilities of the current provider rely on it to identify the current schema. - The default port is usually
2881. - Starting from V1.3.0, Oracle-compatible mode supports encoding and decoding
VARCHAR2/CHAR/CLOBin GBK usingCharacter Set=gbk. If not set, UTF-8 is used.NCHAR/NVARCHAR2are not affected by this parameter. - When using GBK with FreeSql, use the Provider (V1.1.0 or later) with V1.3.0. For complete parameter descriptions, see Connection strings.
Quick start
Convert the connection string into a local configuration (such as a configuration file or environment variable), then create a client and perform a connection check:
using FreeSql;
using FreeSql.Provider.OceanBase;
var connectionString = "<Your connection string>";
using var fsql = new OceanBaseProvider<object>(
connectionString,
null);
fsql.Aop.CurdBefore += (_, e) => Console.WriteLine(e.Sql);
var ok = fsql.Ado.ExecuteConnectTest();
Console.WriteLine($"ConnectTest={ok}");
In single-database scenarios, it is recommended to use IFreeSql as a singleton.
Complete example
Table creation, insertions, deletions, updates, and queries, as well as pagination, are performed in the same way as with regular FreeSql. Use <your connection string> for the connection string.
using System;
using FreeSql;
using FreeSql.DataAnnotations;
using FreeSql.Provider.OceanBase;
var connectionString =
"<your connection string>";
using var fsql = new OceanBaseProvider<object>(connectionString, null);
fsql.Aop.CurdBefore += (_, e) => Console.WriteLine(e.Sql);
fsql.Aop.CurdAfter += (_, e) => Console.WriteLine($"Rows={e.AffectedRows});
fsql.CodeFirst.SyncStructure<DemoUser>();
var userId = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
fsql.Insert(new DemoUser
{
Id = userId,
Name = "Alice",
Age = 28,
CreatedAt = DateTime.Now,
LastLoginAt = DateTimeOffset.Now
}).ExecuteAffrows();
var user = fsql.Select<DemoUser>()
.Where(x => x.Id == userId)
.First();
Console.WriteLine($"{user.Id} {user.Name} {user.Age}`);
fsql.Update<DemoUser>()
.Set(x => x.Name, "Alice-Updated")
.Set(x => x.Age, 29)
.Where(x => x.Id == userId)
.ExecuteAffrows();
var page = fsql.Select<DemoUser>()
.OrderBy(x => x.Id)
.Page(1, 10)
.ToList();
Console.WriteLine($"PageCount={page.Count});
fsql.Delete<DemoUser>()
.Where(x => x.Id == userId)
.ExecuteAffrows();
[Table(Name = "T_DEMO_USER")]
public class DemoUser
{
[Column(Name = "ID", IsPrimary = true)]
public long Id { get; set; }
[Column(Name = "NAME", StringLength = 100)]
public string Name { get; set; } = string.Empty;
[Column(Name = "AGE")]
public int? Age { get; set; }
[Column(Name = "CREATED_AT")]
public DateTime CreatedAt { get; set; }
[Column(Name = "LAST_LOGIN_AT")]
public DateTimeOffset? LastLoginAt { get; set; }
}
Read/write separation example
The OceanBaseProvider<TMark> constructor supports primary/secondary connection strings:
using var fsql = new OceanBaseProvider<object>(
masterConnectionString,
new[] { slaveConnectionString1, slaveConnectionString2 });
This is suitable for integrating with existing read/write separation scenarios.
Native SQL example
It is recommended to use parameterization first. If you need to execute native SQL, you can use the Ado API:
var count = fsql.Ado.ExecuteScalar<int>(
"select count(1) from T_DEMO_USER where AGE >= :minAge",
new OceanBase.OracleParameter(":minAge", 18));
CodeFirst / DbFirst
The current adapter layer already supports basic CodeFirst and DbFirst capabilities.
CodeFirst
Example of synchronizing table structure based on entities:
fsql.CodeFirst.SyncStructure<DemoUser>();
Default type mapping example (subject to the actual version):
CLR Types |
OceanBase Oracle type |
|---|---|
bool |
number(1) |
int |
number(11) |
long |
number(21) |
decimal |
number(10,2) |
string |
varchar2(255) |
DateTime |
timestamp(6) |
DateTimeOffset |
timestamp(6) with local time zone |
byte[] |
blob |
Guid |
char(36 char) |
If your business has specific requirements for length, precision, or column types, it is recommended to explicitly configure column attributes on the entity rather than relying solely on default mappings.
Note
OceanBase does not support NCLOB; CLOB is recommended. Starting from V1.3.0, the FreeSql Provider uniformly treats NCLOB-related mappings as CLOB to avoid type compatibility issues in CodeFirst / DbFirst scenarios.
DbFirst
var exists = fsql.DbFirst.existsTable("<table name>");
var table = fsql.DbFirst.GetTableByName("<table name>");
var tables = fsql.DbFirst.GetTablesByDatabase("<database or schema name consistent with the connection string's database>");
Suitable for simple metadata reading, inspection, or code generation.
Recommended approach
It is recommended to organize your business project as follows:
- Create
IFreeSqlonce when the application starts. - Reuse it as a singleton through Dependency Injection.
- Continue using the original FreeSql features and CRUD syntax for entities.
- Explicitly specify key metadata such as table names, column names, lengths, and precisions.
This typically requires only replacing the driver and Provider initialization code, with minimal changes to the business layer's CRUD.
Considerations
- Do not omit
databasefrom the connection string. The metadata capability of the current Provider depends ondatabaseto identify the current schema. - When using GBK, set
Character Set=gbkin the connection string and use the V1.3.0 compatible Provider (V1.1.0 or later). - If some "return entity after update/delete" APIs are unavailable, you can use the affected row count API, or query first and then perform the delete.
- For complex databases and tables that span schemas or have schema-participating table names, plan accordingly based on your business needs and do not rely entirely on automatic table creation.
- Keep native SQL parameterized.
Minimum connectivity verification
using FreeSql.Provider.OceanBase;
var fsql = new OceanBaseProvider<object>("<your connection string>", null);
Console.WriteLine(fsql.Ado.ExecuteConnectTest());
A return value of True indicates a successful connection.
