@algochad/prisma-core
Version:
A comprehensive NestJS library that provides EF-Core-like operations using Prisma and GraphQL. Features LINQ-style query builders, advanced data manipulation, GraphQL integration with genql, and a unified API for both Prisma and GraphQL operations. Includ
185 lines (150 loc) • 5.03 kB
Markdown
# LINQ Operations
## 🔗 LINQ Operations
### Synchronous LINQ
Perform LINQ-like operations on collections:
```typescript
import { Enumerable } from '@algochad/prisma-core';
// Create collections
const numbers = Enumerable.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
const users = Enumerable.from([
{ id: 1, name: 'John', age: 25, isActive: true },
{ id: 2, name: 'Jane', age: 30, isActive: false },
{ id: 3, name: 'Bob', age: 35, isActive: true },
]);
// Basic operations
const evenNumbers = numbers.Where((x) => x % 2 === 0).ToArray(); // [2, 4, 6, 8, 10]
const activeUserNames = users
.Where((u) => u.isActive)
.Select((u) => u.name.toUpperCase())
.ToArray(); // ['JOHN', 'BOB']
// Complex chaining
const result = users
.Where((u) => u.age > 25)
.OrderBy((u) => u.name)
.Select((u) => ({
displayName: `${u.name} (${u.age})`,
category: u.age > 30 ? 'Senior' : 'Junior',
}))
.GroupBy((u) => u.category)
.ToArray();
```
#### Filtering and Projection
```typescript
// Advanced filtering
const filtered = enumerable
.Where((x) => x.isActive && x.score > 80)
.Where((x) => x.category === 'Premium')
.ToArray();
// Projection and transformation
const mapped = enumerable
.Select((x) => ({
id: x.id,
displayName: `${x.firstName} ${x.lastName}`,
scorePercentage: `${(x.score * 100).toFixed(1)}%`,
status: x.isActive ? 'Active' : 'Inactive',
}))
.ToArray();
// Flattening collections
const allTags = posts
.SelectMany((post) => post.tags)
.Distinct()
.ToArray();
```
#### Aggregation Operations
```typescript
// Statistical operations
const totalScore = enumerable.Sum((x) => x.score);
const averageAge = enumerable.Average((x) => x.age);
const maxScore = enumerable.Max((x) => x.score);
const minAge = enumerable.Min((x) => x.age);
// Counting and existence
const activeCount = enumerable.Count((x) => x.isActive);
const hasHighScorers = enumerable.Any((x) => x.score > 95);
const allAreActive = enumerable.All((x) => x.isActive);
// Custom aggregation
const customAggregate = enumerable.Aggregate(
0, // initial value
(acc, item) => acc + item.score * item.multiplier,
(result) => result / enumerable.Count(), // final transformation
);
```
#### Grouping and Sorting
```typescript
// Grouping operations
const groupedByCategory = enumerable
.GroupBy((x) => x.category)
.Select((group) => ({
category: group.Key,
items: group.ToArray(),
count: group.Count(),
averageScore: group.Average((x) => x.score),
}))
.ToArray();
// Multiple level sorting
const sortedData = enumerable
.OrderBy((x) => x.category)
.ThenByDescending((x) => x.score)
.ThenBy((x) => x.name)
.ToArray();
// Pagination
const pageSize = 10;
const pageNumber = 2;
const paginatedResults = enumerable
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize)
.ToArray();
```
### Asynchronous LINQ
For CPU-intensive operations or large datasets, use AsyncEnumerable:
```typescript
import { AsyncEnumerable } from '@algochad/prisma-core';
// Create async collections
const asyncNumbers = AsyncEnumerable.from([1, 2, 3, 4, 5]);
const asyncData = AsyncEnumerable.fromAsync(async function* () {
for (let i = 0; i < 1000; i++) {
yield await processDataAsync(i);
}
});
// Async operations
const asyncFiltered = await asyncNumbers
.Where((x) => x % 2 === 0)
.ToArrayAsync(); // [2, 4]
const asyncMapped = await asyncNumbers.Select((x) => x * x).ToArrayAsync(); // [1, 4, 9, 16, 25]
// Complex async processing
const processedData = await asyncData
.Where(async (item) => await isValidAsync(item))
.Select(async (item) => await transformAsync(item))
.Take(100)
.ToArrayAsync();
// Parallel processing for performance
const parallelResults = await AsyncEnumerable.from(largeDataset)
.Select(async (item) => await heavyComputationAsync(item))
.ToArrayAsync(); // Processes items in parallel
```
#### Async Database Integration
```typescript
// Combine database queries with LINQ
async function getProcessedUserData() {
// Get data from database
const users = await repository.user
.Where({ isActive: true })
.ToEnumerable();
// Process with async LINQ
const asyncUsers = AsyncEnumerable.from(users.ToArray());
return await asyncUsers
.Select(async (user) => ({
...user,
posts: await repository.post.Where({ userId: user.id }).Count(),
lastActivity: await getLastActivityAsync(user.id),
preferences: await getUserPreferencesAsync(user.id),
}))
.Where(async (userData) => userData.posts > 0)
.OrderByDescending((userData) => userData.lastActivity)
.Take(50)
.ToArrayAsync();
}
```
## Next Steps
- [Explore the Universal Repository Pattern](./repository-pattern.md)
- [See performance benchmarks](./performance.md)
- [Learn about API reference](./api-reference.md)