Skip to content

Instantly share code, notes, and snippets.

@billgeek
Last active December 1, 2023 11:13
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save billgeek/2e70aab19718e58774d947417900f96c to your computer and use it in GitHub Desktop.
Save billgeek/2e70aab19718e58774d947417900f96c to your computer and use it in GitHub Desktop.
Generic Repository Pattern in VB.NET

Creating a Generic Repository Pattern (VB.NET)

The below example shows how to implement a Repository of objects in a generic fashion. (This is the VB.NET version of my previous GIST) This was adapted and simplified from this article: https://code.msdn.microsoft.com/generic-repository-pattern-ddea2262

Overview

The point of this code is to allow the generic access to any object type in the datastore without the need to define a repository for each object. It is important to note that, although the below examples should work as is, it is recommended to make use of a dependency injection framework as database connection limits are not considered.

Imports System.Data.Entity
Imports System.Linq.Expressions
Imports LinqKit
Public Class EFRepository(Of T As Class)
Implements IRepository(Of T)
Private _context As DbContext
Private _table As DbSet(Of T)
Public Sub New(context As DbContext)
_context = context
_table = context.Set(Of T)()
End Sub
Public Function GetRows(Optional searchCriteria As Expression(Of Func(Of T, Boolean)) = Nothing) As IEnumerable(Of T) Implements IRepository(Of T).GetRows
If searchCriteria Is Nothing Then
Return _table.ToList()
Else
Return _table.Where(searchCriteria).ToList()
End If
End Function
Public Function GetByPage(Of TKey)(searchCriteria As Expression(Of Func(Of T, Boolean)), orderCriteria As Expression(Of Func(Of T, TKey)), orderDescending As Boolean, pageNumber As Integer, recordsPerPage As Integer) As ResultPage(Of T) Implements IRepository(Of T).GetByPage
'1. Search for rows (AsExpandable used as sub-queries do Not play nice with LINQ to SQL. See here: http : //tomasp.net/blog/linq-expand.aspx
Dim rawResults As IQueryable(Of T)
If searchCriteria Is Nothing Then
rawResults = _table
Else
rawResults = _table.AsExpandable().Where(searchCriteria)
End If
'2. Apply ordering
If orderDescending = True Then
rawResults = rawResults.OrderByDescending(orderCriteria)
Else
rawResults = rawResults.OrderBy(orderCriteria)
End If
'3. Skip And take pages
Dim resultingRows As IQueryable(Of T) = rawResults.Skip((pageNumber - 1) * recordsPerPage).Take(recordsPerPage)
'4. Return results
Return New ResultPage(Of T)(resultingRows, rawResults.Count(), resultingRows.Count())
End Function
Public Function GetByKey(key As Object) As T Implements IRepository(Of T).GetByKey
Return _table.Find(key)
End Function
Public Sub Add(record As T) Implements IRepository(Of T).Add
_table.Add(record)
End Sub
Public Sub AddMany(records As IEnumerable(Of T)) Implements IRepository(Of T).AddMany
_table.AddRange(records)
End Sub
Public Sub Update(record As T) Implements IRepository(Of T).Update
_table.Attach(record)
_context.Entry(record).State = EntityState.Modified
End Sub
Public Sub Remove(key As Object) Implements IRepository(Of T).Remove
Dim record As T = _table.Find(key)
_table.Remove(record)
End Sub
Public Sub RemoveMany(records As IEnumerable(Of T)) Implements IRepository(Of T).RemoveMany
_table.RemoveRange(records)
End Sub
Public Sub RemoveAll() Implements IRepository(Of T).RemoveAll
_table.RemoveRange(_table)
End Sub
Public Sub Commit() Implements IRepository(Of T).Commit
_context.SaveChanges()
End Sub
Public Function RowCount(Optional filterCriteria As Expression(Of Func(Of T, Boolean)) = Nothing) As Integer Implements IRepository(Of T).RowCount
If filterCriteria Is Nothing Then
Return _table.Count()
Else
Return _table.Count(filterCriteria)
End If
End Function
End Class
Imports System.Linq.Expressions
Public Interface IRepository(Of T As Class)
Function RowCount(ByVal Optional filterCriteria As Expression(Of Func(Of T, Boolean)) = Nothing) As Integer
Function GetRows(ByVal Optional searchCriteria As Expression(Of Func(Of T, Boolean)) = Nothing) As IEnumerable(Of T)
Function GetByPage(Of TKey)(ByVal searchCriteria As Expression(Of Func(Of T, Boolean)), ByVal orderCriteria As Expression(Of Func(Of T, TKey)), ByVal orderDescending As Boolean, ByVal pageNumber As Integer, ByVal recordsPerPage As Integer) As ResultPage(Of T)
Function GetByKey(ByVal key As Object) As T
Sub Add(ByVal record As T)
Sub AddMany(ByVal records As IEnumerable(Of T))
Sub Update(ByVal record As T)
Sub Remove(ByVal key As Object)
Sub RemoveMany(ByVal records As IEnumerable(Of T))
Sub RemoveAll()
Sub Commit()
End Interface
Imports System.Runtime.Serialization
<DataContract()>
Public Class ResultPage(Of T As Class)
<DataMember(Name:="results")>
Public Property Results As IEnumerable(Of T)
<DataMember(Name:="totalRecords")>
Public Property TotalRecords As Long?
<DataMember(Name:="returnedRecords")>
Public Property ReturnedRecords As Long?
Public Sub New()
End Sub
Public Sub New(ByVal lResults As IEnumerable(Of T), ByVal Optional lTotalRecords As Long? = Nothing, ByVal Optional lReturnedRecords As Long? = Nothing)
TotalRecords = lTotalRecords
ReturnedRecords = lReturnedRecords
Results = lResults
End Sub
End Class
Public Class UserService
Private Property _userRepository As IRepository(Of User)
Public Sub New()
_userRepository = New EFRepository(Of User)(New MyDataContext())
End Sub
Public Function GetUsers() As List(Of User)
Return _userRepository.GetRows()
End Function
Public Function CreateUser(ByVal toCreate As UserDto) As UserDto
Dim newUser As New User()
newUser.FirstName = toCreate.FirstName
newUser.LastName = toCreate.LastName
newUser.UserName = toCreate.UserName
_userRepository.Add(newUser)
_userRepository.Commit()
Return New UserDto(newUser)
End Function
Public Function UpdateUser(ByVal toUpdate As UserDto) As UserDto
Dim entity As User = _userRepository.GetByKey(toUpdate.Id)
If Not entity Is Nothing Then
entity.FirstName = toUpdate.FirstName
entity.LastName = toUpdate.LastName
entity.UserName = toUpdate.UserName
_userRepository.Update(entity)
_userRepository.Commit()
End If
Return New UserDto(entity)
End Function
Public Sub RemoveUser(ByVal userId As Integer)
_userRepository.Remove(userId)
_userRepository.Commit()
End Sub
End Class
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment