{"id":21926551,"url":"https://github.com/jchristn/watsonorm","last_synced_at":"2025-09-24T02:22:06.449Z","repository":{"id":65413654,"uuid":"262645365","full_name":"jchristn/WatsonORM","owner":"jchristn","description":"WatsonORM is a lightweight and easy to use object-relational mapper (ORM) in C# for .NET Core.","archived":false,"fork":false,"pushed_at":"2025-02-04T22:27:58.000Z","size":1230,"stargazers_count":23,"open_issues_count":0,"forks_count":9,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-30T06:09:54.247Z","etag":null,"topics":["dotnet","mysql","mysql-database","orm","postgres","postgresql","postgresql-database","repository-pattern","sqlite","sqlserver"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jchristn.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["jchristn"],"custom":["https://paypal.me/joelchristner"]}},"created_at":"2020-05-09T19:37:37.000Z","updated_at":"2025-03-26T20:10:35.000Z","dependencies_parsed_at":"2025-01-16T12:14:34.261Z","dependency_job_id":"5c5dd15d-6d82-4029-bc30-24064c4e49cb","html_url":"https://github.com/jchristn/WatsonORM","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristn%2FWatsonORM","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristn%2FWatsonORM/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristn%2FWatsonORM/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristn%2FWatsonORM/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jchristn","download_url":"https://codeload.github.com/jchristn/WatsonORM/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247445682,"owners_count":20939961,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dotnet","mysql","mysql-database","orm","postgres","postgresql","postgresql-database","repository-pattern","sqlite","sqlserver"],"created_at":"2024-11-28T22:08:36.990Z","updated_at":"2025-09-24T02:22:01.401Z","avatar_url":"https://github.com/jchristn.png","language":"C#","funding_links":["https://github.com/sponsors/jchristn","https://paypal.me/joelchristner"],"categories":[],"sub_categories":[],"readme":"![alt tag](https://github.com/jchristn/watsonorm/blob/master/assets/watson.ico)\n\n# WatsonORM\n\n| Library | Version | Downloads |\n|---|---|---|\n| WatsonORM (all supported database types) | [![NuGet Version](https://img.shields.io/nuget/v/WatsonORM.svg?style=flat)](https://www.nuget.org/packages/WatsonORM/)  | [![NuGet](https://img.shields.io/nuget/dt/WatsonORM.svg)](https://www.nuget.org/packages/WatsonORM) |\n| WatsonORM.Mysql | [![NuGet Version](https://img.shields.io/nuget/v/WatsonORM.Mysql.svg?style=flat)](https://www.nuget.org/packages/WatsonORM.Mysql/)  | [![NuGet](https://img.shields.io/nuget/dt/WatsonORM.Mysql.svg)](https://www.nuget.org/packages/WatsonORM.Mysql) |\n| WatsonORM.Postgresql | [![NuGet Version](https://img.shields.io/nuget/v/WatsonORM.Postgresql.svg?style=flat)](https://www.nuget.org/packages/WatsonORM.Postgresql/)  | [![NuGet](https://img.shields.io/nuget/dt/WatsonORM.Postgresql.svg)](https://www.nuget.org/packages/WatsonORM.Postgresql) |\n| WatsonORM.Sqlite | [![NuGet Version](https://img.shields.io/nuget/v/WatsonORM.Sqlite.svg?style=flat)](https://www.nuget.org/packages/WatsonORM.Sqlite/)  | [![NuGet](https://img.shields.io/nuget/dt/WatsonORM.Sqlite.svg)](https://www.nuget.org/packages/WatsonORM.Sqlite) |\n| WatsonORM.SqlServer | [![NuGet Version](https://img.shields.io/nuget/v/WatsonORM.SqlServer.svg?style=flat)](https://www.nuget.org/packages/WatsonORM.SqlServer/)  | [![NuGet](https://img.shields.io/nuget/dt/WatsonORM.SqlServer.svg)](https://www.nuget.org/packages/WatsonORM.SqlServer) |\n| WatsonORM.Core | [![NuGet Version](https://img.shields.io/nuget/v/WatsonORM.Core.svg?style=flat)](https://www.nuget.org/packages/WatsonORM.Core/)  | [![NuGet](https://img.shields.io/nuget/dt/WatsonORM.Core.svg)](https://www.nuget.org/packages/WatsonORM.Core) |\n \n## Description\n\nWatsonORM is a lightweight and easy to use object-relational mapper (ORM) in C# for .NET Core built on top of DatabaseWrapper.  WatsonORM supports Microsoft SQL Server, Mysql, MariaDB, PostgreSQL, and Sqlite databases, both on-premises and in the cloud.\n\nCore features:\n\n- Annotate classes and automatically create database tables\n- Quickly create, read, update, or delete database records using your own objects\n- Reduce time-to-production and time spent building scaffolding code\n- Programmatic table creation and removal\n\nFor a sample app exercising this library, refer to the ```Test``` project contained within the solution.\n\n## New in v3.0.x\n\n- Dependency update\n- Minor breaking changes\n- Async API support\n- Better support for updating multiple records\n\n## Special Thanks\n\nWe'd like to give special thanks to those who have contributed or helped make the library better!\n\n@Maclay74 @flo2000ace @MacKey-255\n\n## Simple Example\n\nThis example uses ```Sqlite```.  For ```SqlServer```, ```Mysql```, or ```Postgresql```, you must make sure the database exists.  Tables will be automatically created in this example.  Refer to the ```Test``` project for a complete example.\n```csharp\nusing ExpressionTree;\nusing DatabaseWrapper.Core;\nusing Watson.ORM;\nusing Watson.ORM.Core;\n\n// Apply attributes to your class\n[Table(\"person\")]\npublic class Person\n{\n  [Column(\"id\", true, DataTypes.Int, false)]\n  public int Id { get; set; }\n\n  [Column(\"firstname\", false, DataTypes.Nvarchar, 64, false)]\n  public string FirstName { get; set; }\n\n  // Parameter-less constructor is required\n  public Person()\n  {\n  }\n}\n\n// Initialize\nDatabaseSettings settings = new DatabaseSettings(\"./WatsonORM.db\");\nWatsonORM orm = new WatsonORM(settings);\norm.InitializeDatabase();\norm.InitializeTable(typeof(Person)); // initialize one table\norm.InitializeTables(new List\u003cType\u003e { typeof(Person) }); // initialize multiple tables\n\n// Insert \nPerson person = new Person { FirstName = \"Joel\" };\nPerson inserted = orm.Insert\u003cPerson\u003e(person);\n\n// Select\nPerson selected = orm.SelectByPrimaryKey\u003cPerson\u003e(1); \n\n// Select all records\nList\u003cPerson\u003e people = orm.SelectMany\u003cPerson\u003e();\n\n// Select many by column name\nExpr e1 = new Expr(\"id\", OperatorEnum.GreaterThan, 0);\npeople = orm.SelectMany\u003cPerson\u003e(e1);\n\n// Select many by property\nExpr e2 = new Expr(\n  orm.GetColumnName\u003cPerson\u003e(nameof(Person.Id)),\n  DbOperators.GreaterThan,\n  0);\npeople = orm.SelectMany\u003cPerson\u003e(e2);\n\n// Select many by property with pagination\n// Retrieve 50 records starting at record number 10\npeople = orm.SelectMany\u003cPerson\u003e(10, 50, e2);\n\n// Select many with descending order\nResultOrder[] resultOrder = new ResultOrder[1];\nresultOrder[0] = new ResultOrder(\"id\", OrderDirectionEnum.Descending);\npeople = orm.SelectMany\u003cPerson\u003e(null, null, e2, resultOrder);\n\n// Update\ninserted.FirstName = \"Jason\";\nPerson updated = orm.Update\u003cPerson\u003e(inserted);\n\n// Delete\norm.Delete\u003cPerson\u003e(updated); \n```\n\n## Column Naming\n\nColumns can be named *explicitly* by specifying the colum name in the ```Column``` attribute constructor.  Alternatively, constructors that don't include a name can be used, in which case the name of the property will be used as the column name.\n\nExample with explicit naming:\n```csharp\n[Column(\"id\", true, DataTypes.Int, false)] // column name \"id\"\npublic int Id { get; set; }\n\n[Column(\"firstname\", false, DataTypes.Nvarchar, 64, false)] // column name \"firstname\"\npublic string FirstName { get; set; }\n```\n\nExample without explicit naming:\n```csharp\n[Column(true, DataTypes.Int, false)] // column name \"Id\"\npublic int Id { get; set; }\n\n[Column(DataTypes.Nvarchar, 64, false)] // column name \"FirstName\"\npublic string FirstName { get; set; }\n```\n\n## Pagination with SelectMany\n\n```SelectMany``` can be paginated by using the method with either signature ```(int? indexStart, int? maxResults, Expr expr)``` or ```(int? indexStart, int? maxResults, Expr expr, ResultOrder[] resultOrder)```.  ```indexStart``` is the number of records to skip, and ```maxResults``` is the number of records to retrieve.  \n\nPaginated results are always ordered by the primary key column value in ascending order, i.e. ```ORDER BY id ASC``` in the ```Person``` example above.\n\n## Validating One or More Tables\n\nIf you wish to determine if there are any errors or warnings associated with a given ```Type```, use either the ```ValidateTable``` or ```ValidateTables``` API:\n```csharp\nList\u003cstring\u003e errors = new List\u003cstring\u003e();\nList\u003cstring\u003e warnings = new List\u003cstring\u003e();\n\n// validate a single table\nbool success = orm.ValidateTable(typeof(Person), out errors, out warnings);\n\n// validate multiple tables\nbool success = orm.ValidateTables(new List\u003cType\u003e \n  {\n    typeof(Person),\n    typeof(Order),\n    typeof(Inventory)\n  },\n  out errors,\n  out warnings);\n\nif (errors.Count \u003e 0) \n  foreach (string error in errors) Console.WriteLine(error);\n\nif (warnings.Count \u003e 0) \n  foreach (string warning in warnings) Console.WriteLine(warning);\n```\n\n## Using Sqlite\n\nSqlite may not work out of the box with .NET Framework. In order to use Sqlite with .NET Framework, you'll need to manually copy the ```runtimes``` folder into your project output directory. This directory is automatically created when building for .NET Core. To get this folder, build the Test.Sqlite project and navigate to the ```bin/[debug||release]/[netcoreapp*||net5.0||net6.0]``` directory. Then copy the runtimes folder into the project output directory of your .NET Framework application.\n\n## Using SQL Server\n\nIn order to use pagination with SQL Server, the ```SelectMany``` method containing the ```ResultOrder[] resultOrder``` parameter must be used.\n\n## Using MySQL\n\nWhile the ```DateTimeOffset``` type can be used in objects, with MySQL the offset is not persisted.  It is recommended that you store UTC timestamps using the ```DateTime``` type instead.\n\n## Using MariaDB\n\nUse the MySQL constructor.  MySQL constraints apply.\n\n## Version history\n\nRefer to CHANGELOG.md.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjchristn%2Fwatsonorm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjchristn%2Fwatsonorm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjchristn%2Fwatsonorm/lists"}