# 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)
