Core Concepts > Advanced Queries

Views

Queries can also be composed with database views - use them as you would any other table expression.

Let's walk-thru a query, materializing that query as a view in the database, then re-working the original query to use the new view.

Given the following query which selects aggregated data for a person:

IEnumerable<dynamic> aggregates = db.SelectMany(
    dbo.Person.Id,
    db.fx.Sum(dbo.Purchase.TotalPurchaseAmount).As("TotalAmount"),
    db.fx.Count(dbo.Purchase.Id).As("TotalCount")
)
.From(dbo.Person)
.InnerJoin(dbo.Purchase).On(dbo.Purchase.PersonId == dbo.Person.Id)
.GroupBy(
    dbo.Person.Id
)
.Execute();

We can materialize this into a database view named PersonTotalPurchasesView:

CREATE VIEW [dbo].[PersonTotalPurchasesView]
AS
SELECT        
	[dbo].[Person].[Id], 
	SUM([dbo].[Purchase].[TotalPurchaseAmount]) AS [TotalAmount],
	COUNT([dbo].[Purchase].[Id]) AS [TotalCount]
FROM            
	[dbo].[Person] 
	INNER JOIN [dbo].[Purchase] ON [dbo].[Purchase].[PersonId] = [dbo].[Person].[Id]
GROUP BY 
	[dbo].[Person].[Id]

GO

Regenerating code using the dbExpression CLI tool (dbex gen), the code will now contain a database entity (POCO) named PersonTotalPurchasesView, which can be used in any query operation that supports views.
Re-writing the original query using the view and adding a where clause:

//return a PersonTotalPurchasesView, where the person's id is 1.
PersonTotalPurchasesView? person_total = db.SelectOne<PersonTotalPurchasesView>()
    .From(dbo.PersonTotalPurchasesView)
    .Where(dbo.PersonTotalPurchasesView.Id == 1)
    .Execute();

This returns an instance of PersonTotalPurchasesView with properties PersonId, TotalAmount, and TotalCount (the same properties as in the original dynamic).

Using a View in a Select Query

//return a list of PersonTotalPurchasesView, where the list contains any person who has a sum of purchases exceeding $2,500.
IEnumerable<PersonTotalPurchasesView> people_totals = db.SelectMany<PersonTotalPurchasesView>()
    .From(dbo.PersonTotalPurchasesView)
    .Where(dbo.PersonTotalPurchasesView.TotalAmount > 2500)
    .Execute();

Using a View in an Update Query

//update any person's credit limit by 10% (rounding down to the nearest integer) who has spent more than $2,500 and a credit limit exists
int affectedCount = db.Update(
        dbo.Person.CreditLimit.Set(db.fx.Cast(db.fx.Floor(dbo.Person.CreditLimit * 1.1)).AsInt())
    )
    .From(dbo.Person)
    .InnerJoin(dbo.PersonTotalPurchasesView).On(dbo.Person.Id == dbo.PersonTotalPurchasesView.Id)
    .Where(dbo.PersonTotalPurchasesView.TotalAmount > 2500)
    .Execute();

Using a View in a Delete Query

//delete all addresses for any person that hasn't made any purchases
int affectedCount = db.Delete()
	.From(dbo.PersonAddress)
	.InnerJoin(dbo.Person).On(dbo.PersonAddress.PersonId == dbo.Person.Id)
	.LeftJoin(dbo.PersonTotalPurchasesView).On(dbo.Person.Id == dbo.PersonTotalPurchasesView.Id)
	.Where(dbo.PersonTotalPurchasesView.Id == dbex.Null)
	.Execute();
Previous
Subqueries

© 2024 dbExpression. All rights reserved.