Pydantic¶
cast(Model): validate raw data¶
C# Cast<T> only casts references. Here cast validates each element with a pydantic TypeAdapter, so dicts become models and values are coerced:
raw = [{"sku": "A-1", "qty": "2"}]
items = raw.cast(LineItem).to_list() # [LineItem(sku='A-1', qty=2)]
raw.cast(LineItem, strict=True).to_list() # raises ValidationError: no coercion
cast accepts any type a TypeAdapter takes: int, datetime, list[Model], Model | None, and so on.
of_type(Model) is the plain isinstance filter (OfType<T>).
Enumerable[Model] as a field type¶
from pydantic import BaseModel
from pydantic_linq import Enumerable
class Invoice(BaseModel):
lines: Enumerable[LineItem]
inv = Invoice.model_validate({"lines": [{"sku": "A-1", "qty": 2}]})
inv.lines.sum(lambda l: l.qty) # LINQ on the field
inv.model_dump() # {'lines': [{'sku': 'A-1', 'qty': 2}]}
- Validation is the same as for
list[LineItem]: the same coercion, errors and JSON schema ("type": "array"). - It serializes as a plain list.
- An existing
Enumerableis accepted as input too.
Value equality¶
Non-frozen pydantic models compare by field values (==) but are unhashable. The set operators (distinct, union, intersect, except_ and their *_by forms) and contains all use value equality, so they work on such models directly:
[Item(id=1), Item(id=1)].distinct().count() # 1
Performance
Unhashable items fall back to a linear scan. For large sets, use frozen=True models (hashable) or a *_by key that returns a hashable value, such as an id.