diff --git a/AdvancedSearch/EqDemo.AspNetCoreReact.AdvancedSearch.csproj b/AdvancedSearch/EqDemo.AspNetCoreReact.AdvancedSearch.csproj index d6bf539..315c868 100644 --- a/AdvancedSearch/EqDemo.AspNetCoreReact.AdvancedSearch.csproj +++ b/AdvancedSearch/EqDemo.AspNetCoreReact.AdvancedSearch.csproj @@ -1,6 +1,6 @@ - net6.0 + net10.0 true Latest false @@ -13,6 +13,10 @@ + + @@ -30,8 +34,6 @@ - - diff --git a/AdvancedSearch/README.md b/AdvancedSearch/README.md index dd41b68..1760c96 100644 --- a/AdvancedSearch/README.md +++ b/AdvancedSearch/README.md @@ -1,76 +1,266 @@ -# Advanced search — EasyQuery on React 16 +# AdvancedSearch -**Advanced search.** A full-page query builder: users pick the columns, combine any conditions they need, run the query and work with the result — sorting, paging and export. +An ASP.NET Core + React sample that implements the **advanced search scenario**: a full-page query +builder where users pick entities and columns, define conditions, run the query and work with +the result. The page is a React component (`ClientApp/`), and the ASP.NET Core app serves the +EasyQuery API to it. -Part of [EasyQuery samples for ASP.NET Core + React](../README.md). +What you will see on the **EasyQuery** page (`/easy-query`, the last item of the navigation bar): -## Tech stack +* **Entities** panel: the tree of all entities and attributes of the data model; drag or click to add them to the query. +* **Columns** panel: the result columns (with sorting and aggregate functions). +* **Conditions** panel: the query conditions, grouped with AND/OR. +* **Query Menu**: Clear, Load, Storage (New, Save, Save as, Remove) and Fetch data. Three predefined queries are included (`App_Data/dm-nwind/queries`). +* **Result** panel: the result grid (paging by 30 rows) and a chart, with export to PDF, Excel and CSV. + +The browser also remembers the current query (`localStorage`), so the page opens with the last +query you worked on. + +All EasyQuery server settings are in `Startup.cs`: `AddEasyQuery()` in `ConfigureServices` and +`MapEasyQuery(...)` in `Configure`. The client settings are in `ClientApp/src/components/EasyQuery.js`. + +## Tech info | | | |---|---| -| Host | ASP.NET Core 6 | -| UI | React 16 | -| Language | C#, JavaScript | -| EasyQuery | 7.5.0 — `Korzh.EasyQuery.AspNetCore`, `Korzh.EasyQuery.EntityFrameworkCore.Relational`, `Korzh.EasyQuery.SqlServerGate`, `Korzh.EasyQuery.SqLiteGate`, `Korzh.EasyQuery.DataExport` | -| EasyData | 1.6.0 — `EasyData.Exporters.ClosedXML`, `EasyData.Exporters.PdfSharp` | -| EasyQuery.JS | `@easydata/core` 1.6.0, `@easydata/ui` 1.6.0, `@easyquery/core` 7.5.1, `@easyquery/enterprise` 7.5.1, `@easyquery/ui` 7.5.1 | -| Database | SQLite or SQL Server Express LocalDB | +| .NET | .NET 10 (`net10.0`) | +| Platform | ASP.NET Core | +| UI framework | **React 16** (Create React App, `react-scripts` 5), served through `Microsoft.AspNetCore.SpaServices.Extensions` | +| EasyQuery for .NET | **7.5.0**: `Korzh.EasyQuery.AspNetCore`, `Korzh.EasyQuery.EntityFrameworkCore.Relational`, `Korzh.EasyQuery.DataExport`, `Korzh.EasyQuery.SqLiteGate`, `Korzh.EasyQuery.SqlServerGate` | +| EasyData exporters | 1.6.0: `EasyData.Exporters.PdfSharp` (PDF), `EasyData.Exporters.ClosedXML` (Excel) | +| EasyQuery.JS | **7.5.1** from npm (`@easyquery/core`, `@easyquery/ui`, `@easyquery/enterprise` 7.5.1; `@easydata/core`, `@easydata/ui` 1.6.0) | +| Query engine | SQL (`UseSqlManager()`) | +| Data model source | EF Core `DbContext` (`UseDbContext`) | +| EasyQuery API | Middleware: `endpoints.MapEasyQuery(...)`, endpoint `/api/easyquery` | +| Database | SQLite through EF Core 6 (SQL Server is prepared in commented code) | +| Query storage | `FileQueryStore`: JSON files in `App_Data/dm-nwind/queries` | + +## Project structure + +| File / folder | What's inside | +|---|---| +| `Startup.cs` | **The EasyQuery settings**: services (DbContext, CORS, SPA, EasyQuery + exporters), `MapEasyQuery`, the React dev server, demo DB initialization | +| `Program.cs` | The host; it only starts `Startup` | +| `ClientApp/src/components/EasyQuery.js` | **The page component**: `AdvancedSearchView` options and initialization, the query kept in `localStorage` | +| `ClientApp/src/components/EasyQueryHtml.js` | The page markup: the panels and the buttons the view finds by ID | +| `ClientApp/src/index.js`, `ClientApp/src/css/index.css` | The EasyQuery styles (`@easyquery/ui/dist/assets/css/easyquery.ui.css`) and one rule of the sample's own | +| `ClientApp/src/App.js`, `ClientApp/src/components/NavMenu.js` | The `/easy-query` route and its menu item | +| `ClientApp/package.json`, `ClientApp/.npmrc` | The npm packages; the commented settings for the Korzh MyGet feed (pre-release packages) | +| `Models/NWind/`, `Data/AppDbContext.cs` | Entity classes and the DbContext of the demo (Northwind) database | +| `Seed/DbInitializeExtensions.cs` | Creates and seeds the database on the first run | +| `App_Data/dm-nwind/queries/` | Predefined queries for the `nwind` model | +| `App_Data/EqDemoData.zip` | Demo data used to seed the database | +| `Controllers/SampleDataController.cs`, `Counter.js`, `FetchData.js`, `Home.js` | Left over from the project template; not used by EasyQuery | -## Prerequisites +## How to start -* [.NET 6 SDK](https://dotnet.microsoft.com/download) -* [Node.js](https://nodejs.org/) (LTS) -* Visual Studio 2022 17.2 or later, VS Code or any other editor (optional) -* SQL Server Express LocalDB (installed with Visual Studio) +1. Install the [.NET 10 SDK](https://dotnet.microsoft.com/download/dotnet/10.0) (or later) and + [Node.js](https://nodejs.org/) (LTS; `npm` must be in `PATH`). +2. You don't need a license key to start. On the first run the page shows a **No license** + dialog that gets you a free 30-day trial key. A purchased key goes into `appsettings.json` + (`EasyQuery:LicenseKey`); see [License key](../README.md#license-key). +3. Run the project: -## Run it + ```bash + dotnet run + ``` -### Visual Studio + or open `../Samples.React.sln` and start `EqDemo.AspNetCoreReact.AdvancedSearch`. The first + build runs `npm install` in `ClientApp`, which takes a few minutes. In Development, the app + also starts the React dev server (`npm start`). +4. Open https://localhost:5001 (or http://localhost:5000) and click **EasyQuery** in the + navigation bar. -1. Open `Samples.React.sln` from the repository root. -2. Set `EqDemo.AspNetCoreReact.AdvancedSearch` as the startup project. -3. Press F5. +On the first run the application creates the SQLite database `eqdemo-sqlite.db` in the project +folder and fills it with the demo data from `App_Data/EqDemoData.zip`. To reset the data, stop +the app and delete the `eqdemo-sqlite.db*` files. -### Command line +Try it: open **Load** and pick one of the predefined queries, or build your own: add a few +columns from the Entities panel, add a condition, press **Fetch data**. Then export the result +to Excel. -```bash -cd AdvancedSearch -dotnet run -``` +## Next steps + +### Connect the sample to your database + +The sample builds its data model from `AppDbContext`, so every `DbSet` becomes an entity in the +Entities panel. It runs the queries as SQL through the same EF Core connection. The React client +doesn't change. To show your database instead of Northwind: + +1. **Connection string.** In `appsettings.json`, uncomment the `EqDemoDb` entry under + `ConnectionStrings` and put your connection string there. +2. **EF Core provider.** In `Startup.cs` (`ConfigureServices`), replace + `options.UseSqlite(Configuration.GetConnectionString("EqDemoSqLite"))` with the commented + `options.UseSqlServer(Configuration.GetConnectionString("EqDemoDb"))` line. The SQL Server + provider is already referenced. For another database, add its EF Core 6 provider package + (e.g. `Npgsql.EntityFrameworkCore.PostgreSQL`) and use its `Use...` method. + + No DB gate or SQL dialect setting needs to change: while the model comes from a `DbContext`, + the SQL follows its provider. The commented `.RegisterDbGate<...>()` lines are only for + [loading the model from the database schema](#load-the-model-directly-from-the-database-schema-uncomment--change). +3. **Your entities.** Replace the Northwind classes in `Models/NWind/` and the `DbSet`s in + `Data/AppDbContext.cs` with yours. If you don't have the classes yet, generate them from the + database (the example is for SQL Server): + + ```bash + dotnet new tool-manifest + dotnet tool install dotnet-ef --version 10.0.14 + dotnet add package Microsoft.EntityFrameworkCore.Design --version 10.0.14 + dotnet ef dbcontext scaffold "" Microsoft.EntityFrameworkCore.SqlServer --output-dir Models/MyDb --namespace EqDemo.Models --context AppDbContext --context-dir Data --context-namespace EqDemo --no-onconfiguring --force + ``` + + * The first two commands install `dotnet-ef` 10, matching the project's EF Core, for this + folder only. + * `dotnet add package` puts the version into `../Directory.Packages.props`. + * The scaffolding builds the project first, and the first build runs `npm install`. + + The last command overwrites `Data/AppDbContext.cs` with a context for your tables. Then delete + `Models/NWind/`. +4. **Demo seeding.** Remove `app.EnsureDbInitialized(Configuration, env);` at the end of + `Configure` in `Startup.cs`. After that, `Seed/DbInitializeExtensions.cs`, + `App_Data/EqDemoData.zip` and the `Korzh.DbUtils.*` packages are no longer used and can go too. +5. **Northwind leftovers.** Delete the predefined queries in `App_Data/dm-nwind/queries`. The + browser still remembers the last Northwind query, so clear the + `easyquerycomponent-query` key in its local storage, or open the page in a private window. + +Start the app: the Entities panel now lists your tables. + +### Add EasyQuery to your own project -The first build runs `npm install` for the client app, which takes a few minutes. +These steps bring the advanced search page into an existing ASP.NET Core application with a React +client, for example one made from Visual Studio's *React and ASP.NET Core* template: an ASP.NET +Core server project plus a Vite React app. The server works with its database through EF Core. -Then open the URL printed in the console. +1. **Install the server packages** (in the server project): -## License key + ```bash + dotnet add package Korzh.EasyQuery.AspNetCore + dotnet add package Korzh.EasyQuery.EntityFrameworkCore.Relational + dotnet add package Korzh.EasyQuery.DataExport + dotnet add package EasyData.Exporters.PdfSharp + dotnet add package EasyData.Exporters.ClosedXML + ``` -You don't need one to start. On the first run the sample shows a **No license** dialog: enter your -email, then the code we send to it, and you get a free 30-day trial key on the spot. The key is saved to `EasyQuery.lck`; restart the sample to apply it. + The two `EasyData.Exporters.*` packages add PDF and Excel export; leave them out if you don't + need it. `Korzh.EasyQuery.DataExport` gives CSV and HTML for Excel. The sample's versions are in + [`Directory.Packages.props`](../Directory.Packages.props). +2. **Add the server side** in `Program.cs`. Replace `MyDbContext` with your context: -Already have a key? Put it into `appsettings.json` of the app that serves the EasyQuery API and the dialog won't appear: + ```csharp + using EasyData.Export; + using Korzh.EasyQuery.Services; + ... + builder.Services.AddEasyQuery() + .UseSqlManager() + .AddDefaultExporters() + .AddDataExporter("pdf") + .AddDataExporter("excel"); -```json -"EasyQuery": { - "LicenseKey": "your key goes here" -} + // the PDF exporter needs the non-Unicode code pages + System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); + ... + var app = builder.Build(); + ... + app.MapEasyQuery(options => { // the EasyQuery API at /api/easyquery + options.DefaultModelId = "mydb"; + options.SaveNewQuery = false; + options.UseDbContext(); + options.UseQueryStore(_ => new FileQueryStore("App_Data")); + }); + ``` + + The sample also registers an "allow all" CORS policy. You need one only if the browser calls + the API on another origin. With the dev server's proxy (step 4) or with the client served by + the same app, it isn't needed. +3. **Install the client packages** (in the React app's folder), the same versions as in the + sample's [`ClientApp/package.json`](ClientApp/package.json): + + ```bash + npm install @easyquery/core@7.5.1 @easyquery/ui@7.5.1 @easyquery/enterprise@7.5.1 @easydata/core@1.6.0 @easydata/ui@1.6.0 + ``` + + Keep `@easyquery/*` in line with the `Korzh.EasyQuery.*` NuGet packages, and `@easydata/*` + with the `EasyData.*` ones. +4. **Add the UI.** + * Copy [`EasyQuery.js`](ClientApp/src/components/EasyQuery.js) and + [`EasyQueryHtml.js`](ClientApp/src/components/EasyQueryHtml.js) into your components. In a + Vite app, name them `EasyQuery.jsx` and `EasyQueryHtml.jsx`, since Vite compiles JSX only + in `.jsx` files. + * In `EasyQuery.jsx`, remove the `.setAppName(...)` and `.useBackend(...)` lines: they tell + the library that it runs in this sample. Keep `.useEndpoint('/api/easyquery')` in line with + the server. + * Import the styles once, in your entry file: + `import '@easyquery/ui/dist/assets/css/easyquery.ui.css';`. Copy the sample's + `#EntitiesPanel { user-select: none; }` rule into your CSS too. + * Show the component on a route, e.g. with React Router 6 or later, + `} />`. + * In development, send the API calls to the server through the dev server's proxy. In Vite, + that's `server: { proxy: { '/api': 'http://localhost:' } }` in `vite.config.js`. + * The component has no cleanup for unmounting, and React's `` mounts every + component twice in development, so EasyQuery starts twice. Render the page outside + ``. +5. **Connect your data.** `options.UseDbContext<...>()` from step 2 is all it takes: every + `DbSet` of your context becomes an entity, and the queries run through the context's + connection, in the SQL of its provider. Hide what users shouldn't see with + `[EqEntity(false)]` on a class or `[EqEntityAttr(false)]` on a property. +6. **Choose where queries are stored.** `FileQueryStore` keeps them as JSON files in + `App_Data/dm-/queries`; the folder is created on the first save. For anything else, + implement `IQueryStore`. +7. **Set the license key**, as described in [License key](../README.md#license-key). Until there + is one, the page shows the **No license** dialog instead of the query builder. + +More in the docs: [From a sample to your own project](https://korzh.com/easyquery/docs/getting-started/from-sample-to-your-own-project) +and [Getting started for ASP.NET Core + React](https://korzh.com/easyquery/docs/getting-started/asp-net-core/aspnet-core-react). + +### Change the sample + +#### Move the demo database to SQL Server (uncomment) + +To keep the Northwind data but have it in SQL Server, do steps 1 and 2 of +[Connect the sample to your database](#connect-the-sample-to-your-database). The commented +`EqDemoDb` entry has an example LocalDB connection string. Leave the seeding in place: in +`Seed/DbInitializeExtensions.cs`, replace `options.UseSqlite(...)` with the commented +`options.UseSqlServer(...)` line. The demo data is then created in the new database on the +first start. + +#### Load the model directly from the database schema (uncomment + change) + +In `Startup.cs`, uncomment the `.RegisterDbGate()` line (or `SqlServerGate`, to match +your database), and in `MapEasyQuery(...)` replace `options.UseDbContext();` with: + +```csharp +options.UseDbConnection(Configuration.GetConnectionString("EqDemoSqLite")); +options.UseDbConnectionModelLoader(); ``` -Ready to buy? See the [licensing options on korzh.com](https://korzh.com/easyquery?utm_source=github&utm_medium=sample&utm_campaign=eq-samples-aspnetcore-react&utm_content=AdvancedSearch#licensing). +Add `using Microsoft.Data.Sqlite;` at the top of the file. Saved queries refer to entities and +attributes by their IDs, and those of a schema-based model may differ, so the predefined queries +may no longer load. + +#### Let users save new queries + +`options.SaveNewQuery = false` in `MapEasyQuery(...)` means a new query is saved only when the user +presses Save. Set it to `true` to save each new query as soon as it's created. + +#### Don't restore the last query + +`EasyQuery.js` saves the current query to `localStorage` on every change and loads it on start +(`loadQueryFromLocalStorage()`). Remove the `addEventListener('ready', ...)` block to always start +with an empty query. Or set `loadQueryOnStart: true` and `defaultQueryId: ''` in +`viewOptions` to open one of the saved queries instead. + +#### Change the page behavior -## Sample database +In `viewOptions` of `EasyQuery.js`: -The demo database is created and filled automatically on the first start (about a minute or -two). It uses SQLite or SQL Server Express LocalDB; the connection string is in the app's configuration file. +* `widgets.easyGrid.paging.pageSize`: the page size of the result grid; +* `result.showChart`: the chart under the result; +* `serverExporters` and the export links in `EasyQueryHtml.js`: the export formats. `pdf` and + `excel` must be registered with `.AddDataExporter<...>()` in `Startup.cs`. -## Related samples +#### Update EasyQuery.JS or use pre-release packages -* [Advanced search — ASP.NET Core Razor Pages and MVC](https://github.com/easyquery/eq-samples-aspnetcore-razor-mvc/tree/main/Razor.AdvancedSearch) -* [Advanced search — ASP.NET Core + Angular](https://github.com/easyquery/eq-samples-aspnetcore-angular/tree/main/AdvancedSearch) -* [Advanced search (Blazor Server) — ASP.NET Core + Blazor](https://github.com/easyquery/eq-samples-aspnetcore-blazor/tree/main/AdvancedSearch.BlazorServer) -* [Advanced search (Vue 3) — ASP.NET Core + Vue](https://github.com/easyquery/eq-samples-aspnetcore-vue/tree/main/Vue3) -* [Advanced search (Vue 2) — ASP.NET Core + Vue](https://github.com/easyquery/eq-samples-aspnetcore-vue/tree/main/Vue2) -* [Advanced search — ASP.NET Core + Stencil](https://github.com/easyquery/eq-samples-aspnetcore-stencil/tree/main/AdvancedSearch) -* [Advanced search — ASP.NET MVC 5 (.NET Framework)](https://github.com/easyquery/eq-samples-aspnet4-mvc/tree/main/AdvancedSearch) -* [Advanced search (separate front-end and service apps) — ASP.NET MVC 5 (.NET Framework)](https://github.com/easyquery/eq-samples-aspnet4-mvc/tree/main/AdvancedSearch-Multilayered) -* [Advanced search (C#) — ASP.NET Web Forms (.NET Framework)](https://github.com/easyquery/eq-samples-aspnet4-webforms/tree/main/AdvancedSearch) -* [Advanced search (Visual Basic) — ASP.NET Web Forms (.NET Framework)](https://github.com/easyquery/eq-samples-aspnet4-webforms/tree/main/VB.AdvancedSearch) +* Change the `@easyquery/*` and `@easydata/*` versions in `ClientApp/package.json` and run + `npm install`. Keep them in line with the NuGet versions in `../Directory.Packages.props`. +* To get pre-release builds from the Korzh MyGet feed, uncomment the two registry lines in + `ClientApp/.npmrc`. diff --git a/Directory.Packages.props b/Directory.Packages.props index 7951382..4546ba6 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -16,10 +16,9 @@ - - - - - + + + + diff --git a/README.md b/README.md index a2cb77d..a26b8b7 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ to .NET applications. The samples in this repository show it on ASP.NET Core + R | Sample | Scenario | Stack | |---|---|---| -| [Advanced search](AdvancedSearch) | Advanced search | ASP.NET Core 6 · React 16 · C#, JavaScript | +| [AdvancedSearch](AdvancedSearch) | Advanced search | ASP.NET Core 10 · React 16 · C#, JavaScript | * **Advanced search.** A full-page query builder: users pick the columns, combine any conditions they need, run the query and work with the result — sorting, paging and export. @@ -28,7 +28,8 @@ or two; later starts take a few seconds. All NuGet package versions of this repository, EasyQuery and EasyData included, are set in one file: [`Directory.Packages.props`](Directory.Packages.props) (NuGet central package management, which needs Visual Studio 2022 17.2+ or the .NET 6.0.300+ SDK). To try another -EasyQuery version, change it there. +EasyQuery version, change it there. The npm packages (`@easyquery/*`, `@easydata/*`) are in the +`package.json` of the client app; keep them in line with the NuGet ones. ## License key @@ -43,7 +44,82 @@ Already have a key? Put it into `appsettings.json` of the app that serves the Ea } ``` -Ready to buy? See the [licensing options on korzh.com](https://korzh.com/easyquery?utm_source=github&utm_medium=sample&utm_campaign=eq-samples-aspnetcore-react#licensing). +Ready to buy? See the [licensing options on korzh.com](https://korzh.com/easyquery?utm_source=github&utm_medium=sample&utm_campaign=eq-samples-aspnetcore-react#asp-core-edition). + +## Next steps + +### Need a complete reporting application, not a page? + +The samples show one EasyQuery page at a time. If what you're after is a whole self-service +reporting portal, start from [EasyReport Starter Kit (ERSK)](https://korzh.com/easy-report-starter-kit?utm_source=github&utm_medium=sample&utm_campaign=eq-samples-aspnetcore-react) +instead. It's a ready-made ASP.NET Core solution built on EasyQuery, with its full source code +and a Clean Architecture layout, that you rebrand and extend: + +* users create, edit and share reports themselves, in the visual query builder; +* results as tables, charts and pivot tables, with grouping and totals; +* user management with roles and guest access; +* several database connections (SQL Server, MySQL, PostgreSQL, Oracle), multi-tenancy, and + scheduled reports sent by email as Excel, PDF or CSV (Pro edition). + +See it in action at [easy.report](https://easy.report), the live demo of ERSK. + +### Connect a sample to your database + +The sample runs on its own demo database. Here is how you can connect it to your own data +instead: keep the sample as it is and swap the database under it. The ASP.NET Core part reaches +the data through EF Core — an `AppDbContext` with the Northwind entities in `Models/NWind/` — and +builds the EasyQuery data model from it, so the change is about that `DbContext` and its +connection. The React client stays as it is: + +1. **Point the connection string at your database** in `appsettings.json`. +2. **Switch the EF Core provider** (`options.UseSqlite(...)` in `Startup.cs`) to yours. The + SQL Server line is already there, commented out; for another database add its EF Core + provider package. +3. **Replace the demo `DbContext`** with yours: your entity classes instead of `Models/NWind/`, + your `DbSet`s in `Data/AppDbContext.cs`. No classes yet? `dotnet ef dbcontext scaffold` + generates them from the database. +4. **Turn off the demo seeding**: the `EnsureDbInitialized(...)` call at the end of `Startup.cs`. + It creates the Northwind tables and fills them on the first start. +5. **Remove what refers to Northwind**: the predefined queries in `App_Data/dm-nwind`. + +The model is built from the whole `DbContext`, so all its entities show up in the query builder +at once. The sample's own steps: + +| Sample | Data model | Steps | +|---|---|---| +| Advanced search | Whole `DbContext`, SQL | [AdvancedSearch](AdvancedSearch/README.md#connect-the-sample-to-your-database) | + +### Add EasyQuery to your own project + +To get the same page into an application you already have, repeat what the sample does, step by +step: + +1. **Install the packages.** On the server: `Korzh.EasyQuery.AspNetCore` and + `Korzh.EasyQuery.EntityFrameworkCore.Relational` (the SQL engine), and, if users should + export the result, the exporters: `Korzh.EasyQuery.DataExport` (CSV and HTML for Excel), + `EasyData.Exporters.ClosedXML` (Excel files), `EasyData.Exporters.PdfSharp` (PDF). In the + React app: `@easyquery/core`, `@easyquery/ui`, `@easyquery/enterprise`, `@easydata/core` and + `@easydata/ui`. +2. **Add the server side**: `AddEasyQuery()` in the services and `MapEasyQuery(...)` in the + request pipeline. +3. **Add the UI**: copy the React component that holds the EasyQuery widgets, with its markup + and styles, and give it a route. +4. **Connect your data**: tell EasyQuery your `DbContext`. The queries then run through its + connection, in the SQL of its provider. +5. **Choose where queries are stored**: files in `App_Data`, as in the sample, or your own + `IQueryStore`. +6. **Set the license key**, as described in [License key](#license-key). Until there is one, + the page shows the **No license** dialog instead of the EasyQuery widgets. + +The exact packages, code and files: + +| Sample | What you copy | Steps | +|---|---|---| +| Advanced search | The `MapEasyQuery` settings, the `EasyQuery` component and its markup | [AdvancedSearch](AdvancedSearch/README.md#add-easyquery-to-your-own-project) | + +For the details behind each step, see [From a sample to your own project](https://korzh.com/easyquery/docs/getting-started/from-sample-to-your-own-project) +and [Getting started for ASP.NET Core + React](https://korzh.com/easyquery/docs/getting-started/asp-net-core/aspnet-core-react) +in the documentation. ## Other platforms