Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 347ef9b

Browse files
authored
Oracle .NET AI vector sample and repo README updates (#459)
* Oracle .NET AI vector sample upload * Update repo README.md * Update samples README.md
1 parent 0567058 commit 347ef9b

File tree

8 files changed

+480
-7
lines changed

8 files changed

+480
-7
lines changed

‎README.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,16 @@ This repository provides .NET code samples for Oracle developers, specifically f
77
and other Oracle .NET components. .NET products for Oracle Database are free of charge. They consist of:
88

99
<ul>
10-
<li>Oracle Data Provider for .NET (ODP.NET) - an optimized ADO.NET data access provider to the Oracle database. ODP.NET allows developers to take advantage of advanced Oracle database functionality, including Real Application Clusters, XML DB, and self-updating client caches. ODP.NET offers three provider types: Core for .NET (Core) runtimes, managed for .NET Framework (100% managed code and easy deployment), and unmanaged for .NET Framework.</li>
10+
<li>Oracle Data Provider for .NET (ODP.NET) - an optimized ADO.NET data access provider to the Oracle database. ODP.NET allows developers to take advantage of advanced Oracle database functionality, including AI vector search, JSON-relational duality views, Real Application Clusters, and self-updating client caches. ODP.NET offers three provider types: Core for .NET (Core) runtimes, managed for .NET Framework (100% managed code and easy deployment), and unmanaged for .NET Framework.</li>
1111
<li>Oracle Developer Tools for Visual Studio - a tightly integrated design-time "Add-in" for Microsoft Visual Studio that provides full Oracle .NET application lifecycle management, including PL/SQL debugging and schema comparison tools.</li>
12-
<li>Oracle Developer Tools for VS Code - enables Visual Studio Code developers to connect to Oracle Database and Oracle Autonomous Database, edit SQL and PL/SQL with autocomplete, Intellisense, breadcrumbs, and syntax coloring, execute SQL and PL/SQL and view and save the results in formats such as .CSV and JSON. The Oracle Database Explorer tree control allows you to quickly explore your database schema, view table data, and edit, execute and save PL/SQL.</li>
1312
<li>Oracle Providers for ASP.NET - a collection of ASP.NET providers that use Oracle Database as the data source. ASP.NET applications can store various types of website state in an Oracle database, which can then be shared across the application.</li>
1413
</ul>
1514

1615
## Getting Started
17-
Oracle .NET components are available individually on NuGet Gallery or bundled together as part of Oracle Data Access Components (ODAC). Provider downloads are available from <a href="https://www.nuget.org/packages?q=oracle">NuGet Gallery<a> and <a href="https://www.oracle.com/database/technologies/net-downloads.html">Oracle .NET download page</a>. Oracle Developer Tools for VS Code or Visual Studio can be downloaded from the <a href="https://marketplace.visualstudio.com/items?itemName=Oracle.oracledevtools">VS Code Marketplace</a> or <ahref="https://marketplace.visualstudio.com/publishers/OracleCorporation">Visual Studio Marketplace</a>, respectively.
16+
Oracle .NET components are available individually on NuGet Gallery or bundled together as part of Oracle Data Access Components (ODAC). Provider downloads are available from <a href="https://www.nuget.org/packages?q=oracle">NuGet Gallery<a> and <a href="https://www.oracle.com/database/technologies/net-downloads.html">Oracle .NET download page</a>. Oracle Developer Tools for Visual Studio can be downloaded from the <a href="https://marketplace.visualstudio.com/publishers/OracleCorporation">Visual Studio Marketplace</a>.
1817

1918
## Tutorials
20-
For beginning Oracle .NET developers, these <a href="https://www.oracle.com/tools/technologies/quickstart-dotnet-for-oracle-database.html">on-premises .NET database tutorials</a> and <a href="https://www.oracle.com/database/technologies/appdev/dotnet/adbdotnetquickstarts.html">Autonomous Database .NET tutorials</a> will assist you in getting started with .NET application development with Oracle Database.
19+
For novice Oracle .NET developers, these <a href="https://www.oracle.com/tools/technologies/quickstart-dotnet-for-oracle-database.html">on-premises .NET database tutorials</a> and <a href="https://www.oracle.com/database/technologies/appdev/dotnet/adbdotnetquickstarts.html">Autonomous Database .NET tutorials</a> will assist you in getting started with .NET application development with Oracle Database.
2120

2221
Oracle .NET video tutorials are available from the <a href="https://www.youtube.com/user/OracleDOTNETTeam">Oracle .NET YouTube site.
2322

@@ -27,7 +26,7 @@ For those that want to build an end-to-end basic .NET web app for Oracle Databas
2726
<ul>
2827
<li><a href="https://docs.oracle.com/en/database/oracle/oracle-data-access-components/index.html">Documentation</a></li>
2928
<li>Contibutions to code samples should review <a href="CONTRIBUTING.md">CONTRIBUTING</a> for more details.</li>
30-
<li>You may use files in this repository only if in compliance with the <a href="LICENSE">LICENSE</a>.</li>
29+
<li>You may use files in this repository only if in compliance with the <a href="LICENSE.txt">LICENSE</a>.</li>
3130
<li>More Oracle .NET development information can be found at the <a href="http://otn.oracle.com/dotnet">Oracle .NET Developer Center</a>.</li>
3231
</ul>
3332

‎samples/README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ Running ODP.NET Core Samples from Command Line
2424

2525
Below is the feature list the samples cover. Each feature's sample has its own subdirectory.
2626

27+
AI Vector
28+
----------------------
29+
* Search Vector Stores and Collections Sample: Load and vectorize data from .NET. Then, perform exact match searches and similarity searches against the data set.
30+
2731
Application Continuity
2832
----------------------
2933
* Sample 1: Unmanaged ODP.NET Application Continuity code sample with setup and runtime demo instructions.
@@ -53,9 +57,9 @@ Autonomous Database
5357
* Managed ODP.NET Samples: Demonstrates how to connect managed ODP.NET to Oracle Autonomous Database via a console and an ASP.NET web app. <br>
5458
* Unmanaged ODP.NET Sample: Demonstrates how to connect unmanaged ODP.NET to Oracle Autonomous Database via a console app.
5559

56-
Azure Active Directory
60+
Azure Active Directory/Microsoft Entra ID
5761
----------------------
58-
* Demonstrates connecting to Oracle Autonomous Database using an Azure Active Directory token with ODP.NET Core, managed, and unmanaged.
62+
* Demonstrates connecting to Oracle Autonomous Database using a Microsoft Entra ID token with ODP.NET Core, managed, and unmanaged.
5963

6064
Bulk Copy
6165
---------
@@ -177,3 +181,4 @@ User-Defined Types (UDT)
177181
* Ref Sample: Demonstrates how to fetch UDTs referenced by REFs. <br>
178182
* Ref Inheritance Sample: Demonstrates how to obtain and update Custom Type objects from OracleRef objects. <br>
179183
* VARRAY Sample: Demonstrates how to map, fetch, and manipulate the Oracle VARRAY as a custom object.
184+
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
using Oracle.VectorData;
2+
using Oracle.ManagedDataAccess.Client;
3+
using Microsoft.Extensions.VectorData;
4+
using Microsoft.Extensions.Configuration;
5+
using System.Text.Json;
6+
7+
namespace OracleAIVectorData;
8+
9+
// This ODP.NET sample app shows various ways to search vector data and collections.
10+
// First, the data (hotels.json) is loaded into a .NET object list.
11+
// The data initially includes hotel names, descriptions, ids, ratings, and parking availability.
12+
// The hotel names and descriptions are then vectorized using the database ONNX embeddings, consisting of 384 dimensions in Float format.
13+
// The entire data set is upserted into the database.
14+
// Finally, four search operations are demonstrated.
15+
// 1. Search by primary key.
16+
// 2. Search scalar value properties.
17+
// 3. Similarity search using cosine similarity.
18+
// 4. Similarity search using Euclidean distance.
19+
// This sample requires Oracle Database 23ai or higher.
20+
// Add Oracle.VectorData and Microsoft.Extensions.Configuration.Json NuGet packages to your project.
21+
22+
public class AIHotelSearchApp
23+
{
24+
public static async Task Main(string[] args)
25+
{
26+
await SearchHotels();
27+
}
28+
static async Task SearchHotels()
29+
{
30+
// Setup ODP.NET connection and vector configuration.
31+
// Set connection string values in AppSettings.json file.
32+
// Add AppSettings.json directory path below or place file in app's output directory.
33+
var configuration = new ConfigurationBuilder()
34+
.AddJsonFile(path: "AppSettings.json", optional: false)
35+
.Build();
36+
37+
string? connStr = configuration.GetSection("Oracle")["ConnectionString"];
38+
OracleDataSource? ds = null;
39+
OracleVectorStore? vs = null;
40+
OracleCollection<int, Hotel>? collection = null;
41+
string collectionName = "Hotels";
42+
43+
try
44+
{
45+
ds = new OracleDataSourceBuilder(connStr).Build();
46+
47+
// Create a vector store
48+
vs = new OracleVectorStore(ds);
49+
50+
// Create a vector collection
51+
collection = (OracleCollection<int, Hotel>)vs.GetCollection<int, Hotel>(collectionName);
52+
53+
// HotelsData.json contains plain text information about various hotels.
54+
// Add Hotels.json directory path below or place file in app's output directory.
55+
string jsonContent = File.ReadAllText("Hotels.json");
56+
List<Hotel>? hotels = JsonSerializer.Deserialize<List<Hotel>>(jsonContent);
57+
58+
// Use the database ONNX generator to create VECTOR(384, FLOAT32) embeddings for each hotel/record.
59+
foreach (Hotel hotel in hotels)
60+
{
61+
hotel.NameEmbedding = await GenerateEmbeddingAsync(ds, hotel.HotelName);
62+
hotel.DescriptionEmbedding = await GenerateEmbeddingAsync(ds, hotel.Description);
63+
}
64+
65+
// Verify the collection exists in the database.
66+
await collection.EnsureCollectionExistsAsync();
67+
68+
// Upsert the records into the database.
69+
await collection.UpsertAsync(hotels);
70+
71+
// Search hotels in the vector collection by primary key.
72+
Console.WriteLine("Search for hotels with ID 5 and 10.");
73+
Console.WriteLine("===============================================================================");
74+
IAsyncEnumerable<Hotel> hotelsById = collection.GetAsync([5, 10]);
75+
await foreach (Hotel hotel in hotelsById)
76+
{
77+
Output(hotel);
78+
}
79+
Console.WriteLine();
80+
81+
// Search hotels by their characteristics, such as rating and parking availability.
82+
Console.WriteLine("Search for hotels with a 9 or higher rating and parking.");
83+
Console.WriteLine("===============================================================================");
84+
IAsyncEnumerable<Hotel> hotelsByFilter2 = collection.GetAsync(r => r.Rating >= 9 && r.HasParking == true, 3);
85+
await foreach (Hotel hotel in hotelsByFilter2)
86+
{
87+
Output(hotel);
88+
}
89+
Console.WriteLine();
90+
91+
// Search hotels by their names. Return top three most similar matches.
92+
// Provide a search term, such as "beach". Generate a vector embedding using the search term.
93+
// ODP.NET performs a similarity search using the hotel name and search term embeddings.
94+
// The cosine similarity metric is used to calculate vector distances to find the best matches.
95+
// Scores closer to zero are more similar. Higher scores mean more dissimilarity.
96+
// Results are ranked from most similar to least.
97+
string hotelNameSearchStr = "beach";
98+
99+
var nameEmbedding = await GenerateEmbeddingAsync(ds, hotelNameSearchStr);
100+
// Specify the search option for hotel name.
101+
VectorSearchOptions<Hotel> nameOptions = new() { VectorProperty = r => r.NameEmbedding };
102+
IAsyncEnumerable<VectorSearchResult<Hotel>> namesVectorSearch = collection.SearchAsync(nameEmbedding, top: 3, nameOptions);
103+
104+
int rank = 1;
105+
Console.WriteLine($"Hotel name similarity search with \"{hotelNameSearchStr}\".");
106+
Console.WriteLine("===============================================================================");
107+
await foreach (VectorSearchResult<Hotel> searchResult in namesVectorSearch)
108+
{
109+
Console.WriteLine(rank + $". {searchResult.Record.HotelName}");
110+
Console.WriteLine($"Score : {searchResult.Score}");
111+
Console.WriteLine();
112+
rank++;
113+
}
114+
Console.WriteLine();
115+
116+
// Search hotels using their descriptions. Return top three most similar matches.
117+
// Provide a search phrase or sentence. Generate its vector embedding.
118+
// ODP.NET performs a similarity search using the hotel description and search text embeddings.
119+
// The Euclidean distance metric is used to calculate vector distances to find the best matches.
120+
string descriptionSearchStr = "I want a hotel with nature activities.";
121+
var descriptionEmbedding = await GenerateEmbeddingAsync(ds, descriptionSearchStr);
122+
123+
// Specify the search option for hotel description.
124+
VectorSearchOptions<Hotel> descriptionOptions = new() { VectorProperty = r => r.DescriptionEmbedding };
125+
IAsyncEnumerable<VectorSearchResult<Hotel>> descriptionVectorSearch = collection.SearchAsync(descriptionEmbedding, top: 3, descriptionOptions);
126+
127+
rank = 1;
128+
Console.WriteLine($"Hotel description similarity search with \"{descriptionSearchStr}\".");
129+
Console.WriteLine("===============================================================================");
130+
await foreach (VectorSearchResult<Hotel> searchResult in descriptionVectorSearch)
131+
{
132+
Console.WriteLine(rank + $". {searchResult.Record.HotelName}");
133+
Console.WriteLine($"Score : {searchResult.Score}");
134+
Console.WriteLine($"Description: {searchResult.Record.Description}");
135+
Console.WriteLine();
136+
rank++;
137+
}
138+
}
139+
140+
finally
141+
{
142+
// Clean up and delete the collection
143+
if (vs != null) { await vs.EnsureCollectionDeletedAsync(collectionName); }
144+
ds?.Dispose();
145+
vs?.Dispose();
146+
collection?.Dispose();
147+
}
148+
}
149+
150+
// Generate embeddings in ONNX format.
151+
// This app uses Hugging Face's all-MiniLM-L12-v2 model for all its embeddings.
152+
static async Task<float[]> GenerateEmbeddingAsync(OracleDataSource ds, string searchText, CancellationToken cancellationtoken = default)
153+
{
154+
using (OracleConnection conn = await ds.OpenConnectionAsync(cancellationtoken))
155+
{
156+
using (OracleCommand cmd = new OracleCommand($"SELECT TO_VECTOR(VECTOR_EMBEDDING(ALL_MINILM_L12_V2 USING :1 as DATA), 384, FLOAT32)", conn))
157+
{
158+
cmd.Parameters.Add("searchStr", OracleDbType.Varchar2, null, System.Data.ParameterDirection.Input);
159+
cmd.Parameters[0].Value = searchText;
160+
return (float[])cmd.ExecuteScalar();
161+
}
162+
}
163+
}
164+
165+
// Output the hotel's information to the console.
166+
static void Output(Hotel hotel)
167+
{
168+
Console.WriteLine($"Hotel Name = {hotel.HotelName}");
169+
Console.WriteLine($"Hotel Id = {hotel.HotelId}");
170+
Console.WriteLine($"Rating = {hotel.Rating}");
171+
Console.WriteLine($"HasParking = {hotel.HasParking}");
172+
Console.WriteLine();
173+
}
174+
}
175+
/* Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved. */
176+
177+
/******************************************************************************
178+
*
179+
* You may not use the identified files except in compliance with The MIT
180+
* License (the "License.")
181+
*
182+
* You may obtain a copy of the License at
183+
* https://github.com/oracle/Oracle.NET/blob/master/LICENSE.txt
184+
*
185+
* Unless required by applicable law or agreed to in writing, software
186+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
187+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
188+
*
189+
* See the License for the specific language governing permissions and
190+
* limitations under the License.
191+
*
192+
*****************************************************************************/

‎samples/ai-vector/AppSettings.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"Oracle": {
3+
"ConnectionString": "User Id=ADMIN; Password=<PASSWORD>; Data Source=<DATA SOURCE>;"
4+
}
5+
}

‎samples/ai-vector/Hotel.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using Microsoft.Extensions.VectorData;
2+
3+
namespace OracleAIVectorData
4+
{
5+
public class Hotel
6+
{
7+
[VectorStoreKey]
8+
public int HotelId { get; set; }
9+
10+
[VectorStoreData]
11+
public string HotelName { get; set; }
12+
13+
[VectorStoreData]
14+
public float Rating { get; set; }
15+
16+
[VectorStoreData]
17+
public bool HasParking { get; set; }
18+
19+
[VectorStoreData]
20+
public string Description { get; set; }
21+
22+
//Oracle has numerous vector distance functions to identify the most relevant results.
23+
//Let's use cosine similarity for the hotel name vectors.
24+
[VectorStoreVector(Dimensions: 384, DistanceFunction = DistanceFunction.CosineDistance)]
25+
public float[] NameEmbedding { get; set; }
26+
27+
//Let's use Euclidean distance for the hotel description vectors.
28+
[VectorStoreVector(Dimensions: 384, DistanceFunction = DistanceFunction.EuclideanDistance)]
29+
public float[] DescriptionEmbedding { get; set; }
30+
}
31+
}
32+
/* Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved. */
33+
34+
/******************************************************************************
35+
*
36+
* You may not use the identified files except in compliance with The MIT
37+
* License (the "License.")
38+
*
39+
* You may obtain a copy of the License at
40+
* https://github.com/oracle/Oracle.NET/blob/master/LICENSE.txt
41+
*
42+
* Unless required by applicable law or agreed to in writing, software
43+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
44+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45+
*
46+
* See the License for the specific language governing permissions and
47+
* limitations under the License.
48+
*
49+
*****************************************************************************/

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /