Get up and running with Weaviate.Client.Managed in 5 minutes.
- .NET 8.0+ or .NET 9.0+
- A running Weaviate instance (local or cloud)
dotnet add package Weaviate.Client.ManagedCreate a C# class with Managed attributes:
using Weaviate.Client.Managed.Attributes;
using Weaviate.Client.Models;
[WeaviateCollection("Products")]
public class Product
{
[WeaviateUUID]
public Guid Id { get; set; }
[Property]
[Index(Filterable = true, Searchable = true)]
public string Name { get; set; } = "";
[Property]
public string Description { get; set; } = "";
[Property]
[Index(Filterable = true, RangeFilters = true)]
public decimal Price { get; set; }
[Property]
[Index(Filterable = true)]
public bool InStock { get; set; }
// Vector for semantic search
[Vector<Vectorizer.Text2VecOpenAI>(
Model = "text-embedding-ada-002",
SourceProperties = [nameof(Name), nameof(Description)]
)]
public float[]? Embedding { get; set; }
}The WeaviateContext provides an EF Core-like experience with CollectionSet<T> properties:
using Weaviate.Client.Managed.Context;
public class StoreContext : WeaviateContext
{
public StoreContext(WeaviateClient client) : base(client) { }
public CollectionSet<Product> Products { get; set; } = null!;
}using Weaviate.Client;
using Weaviate.Client.Managed.Extensions;
var client = new WeaviateClient(new WeaviateConfig
{
Host = "localhost:8080"
});
// Create the collection in Weaviate from your model's attributes
await client.Collections.CreateFromClass<Product>();
// Create your context
var context = new StoreContext(client);// Single insert — ID is automatically assigned back to the entity
var product = new Product
{
Name = "Wireless Mouse",
Description = "Ergonomic wireless mouse with long battery life",
Price = 29.99m,
InStock = true
};
await context.Insert(product);
Console.WriteLine($"Inserted with ID: {product.Id}");
// Insert multiple
await context.Products.Insert(
new Product { Name = "Keyboard", Description = "Mechanical keyboard", Price = 79.99m, InStock = true },
new Product { Name = "Monitor", Description = "27-inch 4K display", Price = 399.99m, InStock = false }
);// Wait for data to be indexed
await Task.Delay(500);
// Filter query
var results = await context.Products.Query()
.Where(p => p.Price > 50)
.Where(p => p.InStock)
.Limit(10)
.Execute();
// Each result wraps the entity, its ID, and optional metadata
foreach (var result in results)
{
Console.WriteLine($"{result.Object.Name}: ${result.Object.Price}");
}
// Extract just objects when metadata not needed
var products = results.Objects();
// Semantic search with scores
var mouseResults = await context.Products.Query()
.NearText("computer input device")
.WithMetadata(MetadataQuery.Score)
.Limit(5)
.Execute();
foreach (var result in mouseResults)
{
Console.WriteLine($"{result.Object.Name}: {result.Metadata?.Score:F3}");
}
// Hybrid search (combines keyword + semantic)
var hybridResults = await context.Products.Query()
.Hybrid("wireless mouse", alpha: 0.5f)
.Where(p => p.InStock)
.Limit(10)
.Execute();// Find by ID
var found = await context.Products.Find(product.Id);
// Update (uses entity's [WeaviateUUID] property)
found.Price = 24.99m;
await context.Update(found);
// Delete by ID
await context.Delete<Product>(product.Id);Insert multiple objects in one call, or group operations across collections:
// Batch insert — directly awaitable
await context.Products.Insert(
new Product { Name = "Widget A", Price = 9.99m, InStock = true },
new Product { Name = "Widget B", Price = 14.99m, InStock = true }
);
// Cross-collection batch with dependency ordering
var batch = context.Batch();
batch.Insert(new Category { Name = "Gadgets" });
batch.Insert(new Product { Name = "Widget C", Price = 19.99m, InStock = true });
await batch.Execute();
// Delete
await context.Delete<Product>(oldProductId);If your collection has a generative module configured, use .Generate() on any query:
var ragResults = await context.Products.Query()
.NearText("wireless mouse")
.Limit(5)
.Generate(singlePrompt: "Write a one-sentence product description for this item")
.Execute();
foreach (var r in ragResults)
Console.WriteLine($"{r.Object.Name}: {r.Generative?[0]}");If you don't need a full context, use ManagedCollection<T> directly:
// Creates collection and returns a managed wrapper
var products = await client.Collections.CreateManaged<Product>();
// Same operations, just without context
var id = await products.Insert(new Product { Name = "Widget", Price = 9.99m });
var results = await products.Query().NearText("widget").Execute();
var count = await products.Count();
await foreach (var p in products.Iterator())
Console.WriteLine(p.Name);- Complete Guide - Full feature coverage
- Attributes Reference - All attributes explained
- Advanced Patterns - Multi-tenancy, RAG, multi-vector
- Architecture - Understanding the system design
- API Reference - Complete API surface
Data types are automatically inferred from C# types:
[Property]
public string Name { get; set; } // → DataType.Text
[Property]
public int Count { get; set; } // → DataType.Int
[Property]
public decimal Price { get; set; } // → DataType.Number
[Property]
public bool Active { get; set; } // → DataType.Boolean
[Property]
public DateTime Created { get; set; } // → DataType.Date
[Property]
public List<string> Tags { get; set; } // → DataType.TextArrayProperty name becomes the vector name:
[Vector<Vectorizer.Text2VecOpenAI>]
public float[]? TitleEmbedding { get; set; } // Vector name: "titleEmbedding"
[Vector<Vectorizer.Text2VecCohere>]
public float[]? ContentEmbedding { get; set; } // Vector name: "contentEmbedding"Link to other collections:
[WeaviateCollection("Articles")]
public class Article
{
[Property]
public string Title { get; set; } = "";
[Reference]
public Category? Category { get; set; }
}
[WeaviateCollection("Category")]
public class Category
{
[Property]
public string Name { get; set; } = "";
}