### Example of Adding a Connection String Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/gencode_runtimeconfiguration.htm This example shows how to add a specific SQL Server connection string using its generated key. ```csharp RuntimeConfiguration.AddConnectionString("ConnectionString.SQL Server (SqlClient)", "data source=.;initial catalog=Northwind;integrated security=SSPI;persist security info=False;packet size=4096"); ``` -------------------------------- ### VB.NET Transaction Save-point Example Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Adapter/gencode_transactions_adapter.htm Demonstrates the same save-point functionality as the C# example, but in VB.NET. It shows how to start a transaction, save an entity, create a save-point, attempt another save, and roll back to the save-point if necessary. ```vbnet Using adapter As new DataAccessAdapter() Try adapter.StartTransaction(IsolationLevel.ReadCommitted, "SavepointRollback") ' first save a new address Dim newAddress As New AddressEntity() ' ... fill the address entity with values ' save it. adapter.SaveEntity(newAddress, True) ' save the transaction adapter.SaveTransaction("SavepointAddress") ' save a new customer Dim newCustomer As New CustomerEntity() ' ... fill the customer entity with values newCustomer.VisitingAddress = newAddress newCustomer.BillingAddress = newAddress Try adapter.SaveEntity(newCustomer, True) Catch(Exception ex) ' something was wrong. ' ... handle ex here. ' roll back to savepoint. adapter.Rollback("SavepointAddress") End Try ' commit the transaction. If the customer save failed, ' only address is saved, otherwise both. adapter.Commit() Catch // fatal error, roll back everything adapter.Rollback() Throw End Try End Using ``` -------------------------------- ### OrderController with QuerySpec Example Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Adapter/Distributed%20systems/gencode_webapicore.htm An example controller demonstrating how to fetch and project data using LLBLGen Pro's QuerySpec. It retrieves orders for a customer and projects them to a DTO. Ensure to add request validation. ```csharp namespace NWSvc.Controllers { [ApiController] [Route("[controller]")] public class OrderController : ControllerBase { [HttpGet] public async Task> GetAsync(string customerId) { // Use a queryspec query which is directly projected to the DTO class hierarchy // at hand and returned in a list. A limit is specified as the OrderBy will end up in // a subquery which requires a limit. var qf = new QueryFactory(); var q = qf.Order.Where(OrderFields.CustomerId == customerId) .Limit(10000) .OrderBy(OrderFields.OrderId.Ascending()).ProjectToOrder(qf); using(var adapter = new DataAccessAdapter()) ``` -------------------------------- ### FieldLikePredicate Examples with Methods Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Filtering%20and%20Sorting/gencode_filteringpredicateclasses.htm Shows practical C# examples of using StartsWith, Contains, Not, CaseInsensitive, and Like methods for generating SQL LIKE clauses. ```csharp // SQL: CompanyName LIKE 'Solution%' var pred1 = CustomerFields.CompanyName.StartsWith("Solution"); ``` ```csharp // SQL: CompanyName LIKE '%Solution%' var pred2 = CustomerFields.CompanyName.Contains("Solution"); ``` ```csharp // SQL: CompanyName NOT LIKE 'Solution%' var pred3 = Functions.Not(CustomerFields.CompanyName.StartsWith("Solution")); ``` ```csharp // SQL: UPPER(CompanyName) LIKE 'SOLUTION%' var pred4 = CustomerFields.CompanyName.StartsWith("SOLUTION") .CaseInsensitive(); ``` ```csharp // SQL: CompanyName LIKE 'Solution%' var pred5 = CustomerFields.CompanyName.Like("Solution%"); ``` -------------------------------- ### Console Output Example Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/qsg/dfscenario1/generatesourcecode.htm This is an example of the expected console output after running the C# code to retrieve the customer count. It shows the number of customers found and a prompt to continue. ```text Number of customers: 91 Press any key to continue . . . ``` -------------------------------- ### appsettings.json Configuration Example Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/gencode_runtimeconfiguration.htm This JSON file defines connection strings, catalog name overwrites, and tracing settings for LLBLGen Pro. ```json { "LLBLGen":{ "ConnectionStrings": { "ConnectionString.SQL Server (SqlClient)": "data source=YOURDATABOX;initial catalog=SomeUser;User ID=user;Password=secret;persist security info=False;packet size=4096;Connection Timeout=300" }, "SqlServerCatalogNameOverwrites": [ { "CatalogName": "NewName", "Overwrite": "" } ], "Tracing": { "Switches": { "SqlServerDQE": 0, "ORMGeneral": 0, "ORMStateManagement": 0, "ORMPersistenceExecution": 0, "ORMPlainSQLQueryExecution": 0 }, "Listeners": { "Debug": false, "Console": true, "File": "TraceLog.log" } } } } ``` -------------------------------- ### Async FetchQuery Example (Adapter) Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Async/gencode_async_queryspec.htm Demonstrates how to use the FetchQueryAsync method with an EntityQuery on a DataAccessAdapter. Ensure you have created your EntityQuery beforehand. ```csharp var q = // create entity query here var adapter = new DataAccessAdapter(); var results = await adapter.FetchQueryAsync(q); ``` -------------------------------- ### Supported LINQ Query Example Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Linq/gencode_linq_remarkslimitations.htm This is an example of a LINQ query that is supported by LLBLGen Pro. It demonstrates a basic query selecting customers and their associated orders. ```vbnet Dim q = From c In metaData.Customer _ From o In metaData.Order.Where(Function(o) o.CustomerID="ALFKI") _ Select c ``` -------------------------------- ### MySQL Index Hint Example Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/QuerySpec/gencode_queryspec_generalusage.htm Specifies an index hint on the 'Address' entity to guide the database in using a particular index for the query. ```csharp var qf = new QueryFactory(); var q = qf.Address .WithHint("USE INDEX (idx_fk_city_id)") .Where(AddressFields.City.Contains("Stadt")); ``` -------------------------------- ### Example: TransactionScope with LLBLGen Pro Transaction (C#) Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/SelfServicing/gencode_transactions.htm This C# example demonstrates using a TransactionScope with an LLBLGen Pro Transaction. It shows adding entities to the transaction, saving them, and then allowing the TransactionScope to automatically roll back the transaction when it goes out of scope. Assert statements are used to verify the rollback outcome. ```csharp var newCustomer = new CustomerEntity(); // fill newCustomer's fields. // .. var newAddress = new AddressEntity(); // fill newAddress' fields. // .. // start the scope. using(var ts = new TransactionScope()) { // start a new LLBLGen Pro transaction using(var trans = new Transaction(System.Data.IsolationLevel.ReadCommitted, "Test")) { newCustomer.VisitingAddress = newAddress; newCustomer.BillingAddress = newAddress; // add the entities to save to the LLBLGen Pro transaction trans.Add(newCustomer); trans.Add(newAddress); // save both entities. Assert.IsTrue(newCustomer.Save(true)); } // do not call Complete, as we want to rollback the transaction and see if the rollback indeed succeeds. // as the TransactionScope goes out of scope, the on-going transaction is rolled back. } // at this point the transaction of the previous using block is rolled back. // let the DTC and the system.transactions threads deal with the objects. // this sleep is only needed because we're going to access the data directly after the rollback. In normal code, // this sleep isn't necessary. Thread.Sleep(1000); // test if the data is still there. Shouldn't be as the transaction has been rolled back. var fetchedCustomer = new CustomerEntity(customerId); Assert.AreEqual(EntityState.New, fetchedCustomer.Fields.State); var fetchedAddress = new AddressEntity(addressId); Assert.AreEqual(EntityState.New, fetchedAddress.Fields.State); ``` -------------------------------- ### FieldLikePredicate Examples with Operator Overloads Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Filtering%20and%20Sorting/gencode_filteringpredicateclasses.htm Demonstrates the use of overloaded operators (%) for creating FieldLikePredicate instances, noting that method-based approaches are recommended. ```csharp // SQL: CompanyName LIKE 'Solution%' var pred1 = CustomerFields.CompanyName % "Solution%"); ``` ```csharp // SQL: CompanyName LIKE '%Solution%' var pred2 = CustomerFields.CompanyName % "%Solution%"); ``` -------------------------------- ### Example: TransactionScope with LLBLGen Pro Transaction (VB.NET) Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/SelfServicing/gencode_transactions.htm This VB.NET example demonstrates using a TransactionScope with an LLBLGen Pro Transaction. It shows adding entities to the transaction, saving them, and then allowing the TransactionScope to automatically roll back the transaction when it goes out of scope. Assert statements are used to verify the rollback outcome. ```vbnet Dim NewCustomer As New CustomerEntity() ' fill NewCustomer's fields. ' .. Dim NewAddress As New AddressEntity() ' fill NewAddress' fields. ' .. ' start the scope. Using ts As New TransactionScope() ' start a New LLBLGen Pro transaction Using trans As New Transaction(System.Data.IsolationLevel.ReadCommitted, "Test") NewCustomer.VisitingAddress = NewAddress NewCustomer.BillingAddress = NewAddress ' add the entities to save to the LLBLGen Pro transaction trans.Add(NewCustomer) trans.Add(NewAddress) ' save both entities. Assert.IsTrue(NewCustomer.Save(True)) End Using ' do not call Complete, as we want to rollback the transaction and see if the rollback indeed succeeds. ' as the TransactionScope goes out of scope, the on-going transaction is rolled back. End Using ' at this point the transaction of the previous using block is rolled back. ' let the DTC and the system.transactions threads deal with the objects. ' this sleep is only needed because we're going to access the data directly after the rollback. In normal code, ' this sleep isn't necessary. Thread.Sleep(1000) ' test if the data is still there. Shouldn't be as the transaction has been rolled back. Dim fetchedCustomer As New CustomerEntity(customerId) Assert.AreEqual(EntityState.New, fetchedCustomer.Fields.State) Dim fetchedAddress As New AddressEntity(addressId) Assert.AreEqual(EntityState.New, fetchedAddress.Fields.State) ``` -------------------------------- ### Fetch Employees with Last Order using QuerySpec (C#) Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Adapter/gencode_prefetchpaths_adapter.htm Achieves the same result as the previous example but uses the QuerySpec API for fetching. ```csharp var employees= new EntityCollection(); using(DataAccessAdapter adapter = new DataAccessAdapter()) { var qf = new QueryFactory(); var q = qf.Employee .WithPath(EmployeeEntity.PrefetchPathOrders .WithOrdering(OrderFields.OrderDate.Descending()) .WithLimit(1)); adapter.FetchQuery(q, employees); } ``` -------------------------------- ### SQL Server Target Hint Example Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/QuerySpec/gencode_queryspec_generalusage.htm Applies target hints to a join operand for the 'Customer' entity in a SQL Server query. ```csharp var qf = new QueryFactory(); var q = qf.Customer .WithHint("NOLOCK") .WithHint("FORCESEEK") .From(QueryTarget.InnerJoin(qf.Order.WithHint("FORCESEEK")) .On(CustomerFields.CustomerId.Equal(OrderFields.CustomerId))) .Where(OrderFields.EmployeeId.GreaterThan(4)); ``` -------------------------------- ### Fetch Employees with Last Order using QuerySpec (VB.NET) Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Adapter/gencode_prefetchpaths_adapter.htm Achieves the same result as the previous example but uses the QuerySpec API for fetching, using VB.NET. ```vbnet Dim employees as New EntityCollection(Of EmployeeEntity)() Using adapter As New DataAccessAdapter() Dim qf As New QueryFactory() Dim q = qf.Employee _ .WithPath(EmployeeEntity.PrefetchPathOrders _ .WithOrdering(OrderFields.OrderDate.Descending()) _ .WithLimit(1)) adapter.FetchQuery(q, employees) End Using ``` -------------------------------- ### Binding Configuration to LlblgenOptions Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/gencode_runtimeconfiguration.htm Example of how to bind configuration data from an IConfiguration object to an instance of the LlblgenOptions class using the Bind() extension method. ```csharp // e.g. in ConfigureServices var options = new LlblgenOptions(); configuration.Bind(options); ``` -------------------------------- ### Console Output Example Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/qsg/mfscenario1/generatesourcecode.htm This is the expected console output when running the C# code snippet that inserts a new customer and order, showing the order count before and after the save operation. ```text Number of orders: 0 Number of orders: 1 Press any key to continue . . . ``` -------------------------------- ### Configure LLBLGen Pro Runtime Framework at Runtime Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/gencode_runtimeconfiguration.htm This example demonstrates setting up connection strings, Data Query Engines (DQE), dependency injection, tracers, and entity-related settings. Ensure this code runs at application startup. ```csharp // ... this code is placed in a method called at application startup RuntimeConfiguration.AddConnectionString("ConnectionString.SQL Server (SqlClient)", "data source=nerd;initial catalog=Northwind;integrated security=SSPI;persist security info=False;packet size=4096"); // Configure the DQE RuntimeConfiguration.ConfigureDQE( c => c.SetTraceLevel(TraceLevel.Verbose) .AddDbProviderFactory(typeof(System.Data.SqlClient.SqlClientFactory)) .SetDefaultCompatibilityLevel(SqlServerCompatibilityLevel.SqlServer2012)); // Configure Dependency Injection RuntimeConfiguration.SetDependencyInjectionInfo( new List() { typeof(AddressEntity).Assembly, this.GetType().Assembly }, new List() { "Northwind", "Authorizers", }); // Configure tracers RuntimeConfiguration.Tracing .SetTraceLevel("ORMPersistenceExecution", TraceLevel.Info) .SetTraceLevel("ORMPlainSQLQueryExecution", TraceLevel.Info); // Configure entity related settings RuntimeConfiguration.Entity .SetMarkSavedEntitiesAsFetched(true) .SetMakeInvalidFieldReadsFatal(true); ``` -------------------------------- ### Configure LLBLGen Pro Runtime in Startup.cs Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Adapter/Distributed%20systems/gencode_webapicore.htm Sets up the LLBLGen Pro runtime by adding connection strings and configuring the Data Access Layer for SQL Server. This is typically done in the ConfigureServices method of your Startup class. ```csharp namespace Service { public class Startup { public Startup(IConfiguration configuration) { this.Configuration = configuration; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // Configure the LLBLGen Pro Runtime here with calls to RuntimeConfiguration RuntimeConfiguration.AddConnectionString("ConnectionString.SQL Server (SqlClient)", this.Configuration.GetConnectionString("ConnectionString.SQL Server (SqlClient)")); RuntimeConfiguration.ConfigureDQE(c => { // add more here... c.AddDbProviderFactory(typeof(Microsoft.Data.SqlClient.SqlClientFactory)); }); services.AddControllers(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo {Title = "Service", Version = "v1"}); }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if(env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseSwagger(); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Service v1")); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } private IConfiguration Configuration { get; } } } ``` -------------------------------- ### Declarative Data Binding with LLBLGenProDataSource2 Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Adapter/Databinding%20at%20designtime%20and%20runtime/gencode_databinding_adapter_aspnet2x.htm This example demonstrates declarative data binding for filtering orders based on customer selection and shipping country using ASP.NET controls and LLBLGenProDataSource2. No code-behind is required for this setup. ```aspx <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <%@ Register Assembly="SD.LLBLGen.Pro.ORMSupportClasses.Web" Namespace="SD.LLBLGen.Pro.ORMSupportClasses" TagPrefix="llblgenpro" %> Untitled Page
All customers:
Customers:
ShipCountry: Spain Germany
``` -------------------------------- ### Configuring Dependency Injection Information Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/gencode_usingdi.htm This example shows how to specify assemblies to check for instance types and how to filter instance types by namespace. Use filename for local assemblies or fullName for assemblies in the GAC or bin folder. ```xml ``` -------------------------------- ### Custom Employee Authorizer Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/gencode_authorization.htm Implement a custom authorizer for EmployeeEntity to control field access based on user identity. This example restricts access to 'NationalIdnumber' and 'SalariedFlag' fields if the user's name starts with 'John'. ```csharp public class AdventureWorksAuthorizerBase : AuthorizerBase { /// /// Gets the current identity. /// /// protected IIdentity GetCurrentIdentity() { return Thread.CurrentPrincipal.Identity; } } /// /// Class which is used to authorize AdventureWorks entity access. /// /// Used as a singleton. [DependencyInjectionInfo(typeof(EmployeeEntity), "AuthorizerToUse", ContextType = DependencyInjectionContextType.Singleton)] public class AdventureWorksEmployeeAuthorizer : AdventureWorksAuthorizerBase { public AdventureWorksEmployeeAuthorizer() { } /// /// Determines whether the caller can obtain the value for the field with the index /// specified from the entity type specified. /// /// The entity instance to obtain the value from. /// Index of the field to obtain the value for. /// True if the caller is allowed to obtain the value, false otherwise public override bool CanGetFieldValue(IEntityCore entity, int fieldIndex) { bool toReturn = ((EntityType)entity.LLBLGenProEntityTypeValue == EntityType.EmployeeEntity); IIdentity currentIdentity = this.GetCurrentIdentity(); switch((EmployeeFieldIndex)fieldIndex) { case EmployeeFieldIndex.NationalIdnumber: if(currentIdentity.Name.StartsWith("John")) { // deny toReturn = false; } break; default: toReturn = true; break; } return toReturn; } /// /// Determines whether the caller can set the value for the field with the index /// specified of the entity type specified. /// /// The entity instance the field is located in. /// Index of the field to set the value of. /// true if the caller is allowed to set the value, false otherwise public override bool CanSetFieldValue(IEntityCore entity, int fieldIndex) { bool toReturn = ((EntityType)entity.LLBLGenProEntityTypeValue == EntityType.EmployeeEntity); IIdentity currentIdentity = base.GetCurrentIdentity(); switch((EmployeeFieldIndex)fieldIndex) { case EmployeeFieldIndex.SalariedFlag: if(currentIdentity.Name.StartsWith("John")) { // deny toReturn = false; } break; default: toReturn = true; break; } return toReturn; } } ``` -------------------------------- ### Execute Scalar Query with AggregateFunction.Sum (C#) Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/gencode_expressionsaggregates.htm This example shows how to perform a scalar query to get the total price for a specific order using a collection. It calculates the product price using an expression and then aggregates it with Sum. The field specified is replaced by the expression in the query. ```C# var orderDetails = new OrderDetailsCollection(); decimal orderPrice = (decimal)orderDetails.GetScalar(OrderDetailsFieldIndex.OrderId, OrderDetailsFields.Quantity.Mul(OrderDetailsFields.UnitPrice), AggregateFunction.Sum, OrderDetailsFIelds.OrderId.Mul(10254)); ``` -------------------------------- ### LLBLGen Pro .lpt Include Template Example Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/gencode_addingusercode.htm This .lpt template demonstrates how to access the CurrentEntity from the _activeObject Hashtable and dynamically include code based on the entity's name. Ensure the template is saved with a .lpt extension and placed in the correct directory. ```csharp <% EntityDefinition currentEntity = (EntityDefinition)((Hashtable)_activeObject)["CurrentEntity"]; %> /// /// Example of dyn. included code. /// public string IncludedPropertyOf<%=currentEntity.Name%> { get { return "I'm dynamically included in <%=currentEntity.Name%>!";} } ``` -------------------------------- ### CustomerService Web Service Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Adapter/Distributed%20systems/gencode_webservices.htm This C# code defines a web service with methods to get a single customer, get all customers, and save a customer. ```APIDOC ## CustomerService Web Service ### Description This web service provides operations to interact with customer data. It includes methods for fetching a specific customer by ID, retrieving a collection of all customers, and saving customer entity changes. ### Methods - **GetCustomer**: Retrieves a single `CustomerEntity` based on a provided customer ID. - **GetCustomers**: Retrieves a collection of all `CustomerEntity` objects. - **SaveCustomer**: Saves changes to a provided `CustomerEntity`. ### Example Usage (C#) ```csharp [WebService(Namespace="http://www.llblgen.com/examples")] public class CustomerService : System.Web.Services.WebService { [WebMethod] public CustomerEntity GetCustomer(string customerID) { CustomerEntity toReturn = new CustomerEntity(customerID); using(DataAccessAdapter adapter = new DataAccessAdapter()) { adapter.FetchEntity(toReturn); return toReturn; } } [WebMethod] public EntityCollection GetCustomers() { EntityCollection customers = new EntityCollection(new CustomerEntityFactory()); using(DataAccessAdapter adapter = new DataAccessAdapter()) { adapter.FetchEntityCollection(customers, null); return customers; } } [WebMethod] public bool SaveCustomer(CustomerEntity toSave) { using(DataAccessAdapter adapter = new DataAccessAdapter()) { return adapter.SaveEntity(toSave); } } } ``` ### Example Usage (VB.NET) ```vb.net _ Public Class CustomerService Inherits System.Web.Services.WebService _ Public Function GetCustomer(customerID As String) As CustomerEntity Dim toReturn As New CustomerEntity(customerID) Dim adapter As New DataAccessAdapter() Try adapter.FetchEntity(toReturn) Return toReturn Finally adapter.Dispose() End Try End Function _ Public Function GetCustomers() As EntityCollection Dim customers As New EntityCollection(New CustomerEntityFactory()) Dim adapter As New DataAccessAdapter() Try adapter.FetchEntityCollection(customers, Nothing) Return customers Finally adapter.Dispose() End Try End Function _ Public Function SaveCustomer(toSave As CustomerEntity) As Boolean Dim adapter As New DataAccessAdapter() Try Return adapter.SaveEntity(toSave) Finally adapter.Dispose() End Try End Function End Class ``` ``` -------------------------------- ### DynamicQuery Starting Inner Join with EntityRelation Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/QuerySpec/gencode_queryspec_joins.htm Correctly starts a join for a DynamicQuery using an EntityRelation object passed to the From() method via Joins._joinmethod_. ```csharp var q = qf.Create() .From(Joins.Inner(CustomerEntity.Relations.OrderEntityUsingCustomerId)); ``` -------------------------------- ### Fetch Entity with Prefetch Path and Context (C#) Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Adapter/gencode_usingcontext_adapter.htm Demonstrates fetching a customer and its related orders using a PrefetchPath and a Context object. The Context ensures that subsequent fetches can reuse existing entity instances. ```csharp // first part, load the customer and its related order entities. CustomerEntity customer = new CustomerEntity("BLONP"); using(DataAccessAdapter adapter = new DataAccessAdapter()) { Context myContext = new Context(); PrefetchPath2 prefetchPath = new PrefetchPath2(EntityType.CustomerEntity); prefetchPath.Add(CustomerEntity.PrefetchPathOrders); adapter.FetchEntity(customer, prefetchPath, myContext); // ... // customer and its orders are now loaded. } // Say, later on we want to add the order details // of each order of this customer to this graph. We can do that with the following code. using(DataAccessAdapter adapter = new DataAccessAdapter()) { // re-define the prefetch path, as if we're somewhere else in the application PrefetchPath2 prefetchPath = new PrefetchPath2(EntityType.CustomerEntity); prefetchPath.Add(CustomerEntity.PrefetchPathOrders).SubPath.Add(OrderEntity.PrefetchPathOrderDetails); // fetch the customer again. As it is already added to a Context (myContext), the fetch logic // will use that Context object. This fetch action will fetch all data again, but into the same // entity class instances and will for each Order entity loaded, load the Order Detail entities as well. adapter.FetchEntity(customer, prefetchPath); } ``` -------------------------------- ### Get Total Rows for Typed List Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Adapter/gencode_paging_adapter.htm Use this method to get the total count of rows in a typed list by creating a RelationPredicateBucket from GetRelationInfo() and adding predicates. ```csharp var orderCustomer = new OrderCustomerTypedList(); var filter = orderCustomer.GetRelationInfo(); filter.PredicateExpression.Add(CustomerFields.Country == "France"); int amount = 0; using(var adapter = new DataAccessAdapter()) { amount = (int)adapter.GetDbCount(orderCustomer.GetFieldsInfo(), filter, null, false); } ``` -------------------------------- ### Apply Target Hints to Customer Entity for SQL Server Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Linq/gencode_linq_generalusage.htm Demonstrates applying target hints like NOLOCK and FORCESEEK to the Customer entity in a SQL Server query with a join. ```C# var q = from c in metaData.Customer .WithHint("NOLOCK") .WithHint("FORCESEEK") join o in metaData.Order on c.CustomerId equals o.CustomerId where o.EmployeeId > 4 select c; ``` ```VB.NET Dim q = From c In metaData.Customer _ .WithHint("NOLOCK") _ .WithHint("FORCESEEK") _ Join o In metaData.Order On c.CustomerId Equals o.CustomerId _ Where o.EmployeeId > 4 _ Select c ``` -------------------------------- ### Unsupported LINQ Construct Example Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Linq/gencode_linq_remarkslimitations.htm This example demonstrates a LINQ construct that is not supported by LLBLGen Pro and cannot be converted to SQL. Specifically, it involves an IList.Except() operation on a database query. ```vbnet From o In metaData.Order.Where(Function(o) o.CustomerID = c.CustomerID).Take(10) _ Select c.ContactName, o.OrderDate ``` -------------------------------- ### Fetch Data with Database Function Calls (Adapter) Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/gencode_dbfunctioncall.htm Demonstrates fetching data using the adapter pattern, defining resultset fields, and applying database function calls for calculations like order totals and date manipulations. ```csharp var fields = new ResultsetFields(8); fields.DefineField(OrderFields.OrderId, 0, "OrderID"); fields.DefineField(OrderFields.OrderDate, 1, "Month"); fields.DefineField(OrderFields.OrderDate, 2, "Year"); fields.DefineField(OrderFields.OrderDate, 3, "YearPlus4"); fields.DefineField(OrderFields.OrderDate, 4, "OrderTotalWithDiscounts"); fields.DefineField(OrderFields.OrderDate, 5, "OrderTotalWithoutDiscounts"); fields.DefineField(OrderFields.OrderDate, 6, "YearOfGetDate"); fields.DefineField(OrderFields.OrderDate, 7, "RealOrderDate"); fields[1].ExpressionToApply = new DbFunctionCall("MONTH", new object[] { OrderFields.OrderDate }); fields[2].ExpressionToApply = new DbFunctionCall("YEAR", new object[] { OrderFields.OrderDate }); fields[3].ExpressionToApply = new Expression(new DbFunctionCall("YEAR", new object[] { OrderFields.OrderDate }), ExOp.Add, 4); fields[4].ExpressionToApply = new DbFunctionCall("dbo", "fn_CalculateOrderTotal", new object[] { OrderFields.OrderId, 1 }); fields[5].ExpressionToApply = new DbFunctionCall("dbo", "fn_CalculateOrderTotal", new object[] { OrderFields.OrderId, 0 }); fields[6].ExpressionToApply = new DbFunctionCall("YEAR", new object[] { new DbFunctionCall("GETDATE", null) }); var results = new DataTable(); using(var adapter = new DataAccessAdapter()) { adapter.FetchTypedList(fields, results, null); } foreach(DataRow row in results.Rows) { DateTime realOrderDate = (DateTime)row[7]; Assert.AreEqual((int)row[1], realOrderDate.Month); Assert.AreEqual((int)row[2], realOrderDate.Year); Assert.AreEqual((int)row[3], realOrderDate.Year + 4); Assert.AreEqual((int)row[6], DateTime.Now.Year); } ``` -------------------------------- ### FK-PK Synchronization Example in C# Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Adapter/gencode_usingentityclasses_additionalfeatures.htm Demonstrates how setting a Customer entity to an Order entity automatically synchronizes the CustomerID. Also shows how changing CustomerID dereferences the Customer entity. ```csharp OrderEntity myOrder = new OrderEntity(); CustomerEntity myCustomer = new CustomerEntity("CHOPS"); adapter.FetchEntity(myCustomer); myOrder.Customer = myCustomer; // A myOrder.CustomerID = "BLONP"; // B CustomerEntity referencedCustomer = myOrder.Customer; // C ``` -------------------------------- ### Generated SQL with Query Hints Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Linq/gencode_linq_generalusage.htm This SQL demonstrates the output generated when using query hints like 'MERGE JOIN' and 'FORCE ORDER'. ```SQL SELECT DISTINCT [LPA_L1].[Address], [LPA_L1].[City], [LPA_L1].[CompanyName], [LPA_L1].[ContactName], [LPA_L1].[ContactTitle], [LPA_L1].[Country], [LPA_L1].[CustomerID] AS [CustomerId], [LPA_L1].[Fax], [LPA_L1].[Phone], [LPA_L1].[PostalCode], [LPA_L1].[Region] FROM ([Northwind].[dbo].[Customers] [LPA_L1] INNER JOIN [Northwind].[dbo].[Orders] [LPA_L2] ON [LPA_L1].[CustomerID] = [LPA_L2].[CustomerID]) WHERE ((((([LPA_L2].[EmployeeID] > @p1 ))))) OPTION (FORCE ORDER, MERGE JOIN) ``` -------------------------------- ### Explicitly Start and Manage ADO.NET Transaction in VB.NET Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Adapter/gencode_transactions_adapter.htm Use this snippet to explicitly start, commit, or roll back an ADO.NET transaction when performing multiple database operations that must be atomic. Ensure the transaction is managed within a Try-Catch block for proper rollback on error. The connection is kept open until Commit() or Rollback() is called. ```vbnet ' create adapter for fetching and the transaction. Using adapter As New DataAccessAdapter() ' start the transaction. adapter.StartTransaction(IsolationLevel.ReadCommitted, "TwoUpates") Try ' fetch the two entities Dim customer As New CustomerEntity("CHOPS") Dim order As New OrderEntity(10254) adapter.FetchEntity(customer) adapter.FetchEntity(order) ' alter the entities customer.Fax = "12345678" order.Freight = 12 ' save the two entities again. adapter.SaveEntity(customer) adapter.SaveEntity(order) ' done adapter.Commit() Catch ' abort, roll back the transaction adapter.Rollback() ' bubble up exception Throw End Try End Using ``` -------------------------------- ### Google Cloud Join and Secondary Index Hint Example Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/QuerySpec/gencode_queryspec_generalusage.htm Specifies join hints and secondary index hints for elements in a query, applicable to Google Cloud environments. ```csharp var qf = new QueryFactory(); var q = qf.TypesTab .From(QueryTarget.InnerJoin(qf.Notnulltab.WithHint("FORCE_JOIN_ORDER=TRUE") .WithHint("FORCE_INDEX=NOTNULLTABIDX")) .On(TypesTabFields.Id.Equal(NotnulltabFields.Id))) .Where(TypesTabFields.Id.GreaterEqual(1000)) .OrderBy(TypesTabFields.Id.Ascending()); ``` -------------------------------- ### Construct Multi-Node Prefetch Path with Sorting (PrefetchPath) Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Tutorials%20And%20Examples/examples_howdoi.htm Builds a prefetch path for Employee entities with a multi-node structure and sorting on one of the nodes. This example shows how to specify sorting for prefetched orders and then chain sub-paths for shippers and customers. ```C# var path = new PrefetchPath(EntityType.EmployeeEntity); var sorter = new SortExpression(); sorter.Add(OrderFields.OrderDate.Descending()); path.Add(EmployeeEntity.PrefetchPathOrders, 0, null, null, sorter) .SubPath.Add(OrderEntity.PrefetchPathShippers); path.Add(EmployeeEntity.PrefetchPathCustomers) .SubPath.Add(CustomerEntity.PrefetchPathOrders); ``` -------------------------------- ### Explicitly Start and Manage ADO.NET Transaction in C# Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Adapter/gencode_transactions_adapter.htm Use this snippet to explicitly start, commit, or roll back an ADO.NET transaction when performing multiple database operations that must be atomic. Ensure the transaction is managed within a try-catch block for proper rollback on error. The connection is kept open until Commit() or Rollback() is called. ```csharp // create adapter for fetching and the transaction. using(var adapter = new DataAccessAdapter()) { // start the transaction explicitly. adapter.StartTransaction(IsolationLevel.ReadCommitted, "TwoUpates"); try { // fetch the two entities var customer = new CustomerEntity("CHOPS"); OrderEntity order = new OrderEntity(10254); adapter.FetchEntity(customer); adapter.FetchEntity(order); // alter the entities customer.Fax = "12345678"; order.Freight = 12; // save the two entities again adapter.SaveEntity(customer); adapter.SaveEntity(order); // done adapter.Commit(); } catch { // abort, roll back the transaction adapter.Rollback(); // bubble up exception throw; } } ``` -------------------------------- ### Fetch Entity with Prefetch Path and Context (VB.NET) Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Adapter/gencode_usingcontext_adapter.htm Demonstrates fetching a customer and its related orders using a PrefetchPath and a Context object in VB.NET. The Context ensures that subsequent fetches can reuse existing entity instances. ```vbnet ' VB.NET ' first part, load the customer and its related order entities. Dim customer As New CustomerEntity("BLONP") Using adapter As New DataAccessAdapter() Dim myContext As New Context() Dim prefetchPath As New PrefetchPath2(CInt(EntityType.CustomerEntity)) prefetchPath.Add(CustomerEntity.PrefetchPathOrders) adapter.FetchEntity(customer, prefetchPath, myContext) ' ... ' customer and its orders are now loaded. End Using ' Say, later on we want to add the order details ' of each order of this customer to this graph. We can do that with the following code. Using adapter As New DataAccessAdapter() ' redefine the prefetch path, as if we're somewhere else in the application Dim prefetchPath As new PrefetchPath2(EntityType.CustomerEntity)) prefetchPath.Add(CustomerEntity.PrefetchPathOrders).SubPath.Add(OrderEntity.PrefetchPathOrderDetails) ' fetch the customer again. As it is already added to a Context (myContext), the fetch logic ' will use that Context object. This fetch action will fetch all data again, but into the same ' objects and will for each Order entity loaded load the Order Detail entities as well. adapter.FetchEntity(customer, prefetchPath) End Using ``` -------------------------------- ### Generated SQL with Tag Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/QuerySpec/gencode_queryspec_generalusage.htm The tag is prepended to the SQL query as a comment. This is the SQL produced by the previous C# example. ```sql /* QuerySpec/EntityFetches/QueryTagTest_Scalar */ SELECT TOP(@p2) COUNT(*) AS [CF] FROM [Northwind].[dbo].[Customers] WHERE (([Northwind].[dbo].[Customers].[Country] = @p3)) ``` -------------------------------- ### FieldCompareSetPredicate SQL Equivalents Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Filtering%20and%20Sorting/gencode_filteringpredicateclasses.htm Provides SQL syntax examples for FieldCompareSetPredicate, demonstrating its use with subqueries for IN() and EXISTS() clauses. ```sql Field IN (SELECT OtherField FROM OtherTable WHERE Foo=2) EXISTS (SELECT * FROM OtherTable) ``` -------------------------------- ### WebAPI Method to Fetch All Products with Category Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Adapter/Distributed%20systems/gencode_webservices.htm This example demonstrates fetching all products along with their pre-fetched category entities using LinqMetaData in a WebAPI context. Ensure DataAccessAdapter is properly initialized. ```csharp public IEnumerable GetAllProducts() { using(var adapter = new DataAccessAdapter()) { var metaData = new LinqMetaData(adapter); return metaData.Product.WithPath(p=>p.Prefetch(x=>x.Category)).ToList(); } } ``` -------------------------------- ### SQL Derived Table Example Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/gencode_derivedtabledynamicrelation.htm Illustrates a SQL query using a derived table in the FROM clause, joined with the Orders table. ```sql SELECT o.* FROM ( SELECT CustomerId FROM Customers WHERE Country = @country ) c INNER JOIN Orders o ON c.CustomerId = o.CustomerId ``` -------------------------------- ### FK-PK Synchronization Example in VB.NET Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Adapter/gencode_usingentityclasses_additionalfeatures.htm Demonstrates how setting a Customer entity to an Order entity automatically synchronizes the CustomerID. Also shows how changing CustomerID dereferences the Customer entity. ```vbnet Dim myOrder As New OrderEntity() Dim myCustomer As New CustomerEntity("CHOPS") adapter.FetchEntity(myCustomer) myOrder.Customer = myCustomer ' A myOrder.CustomerID = "BLONP" ' B Dim referencedCustomer As CustomerEntity = myOrder.Customer ' C ``` -------------------------------- ### SQL Server CE Desktop Connection String Example Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/FeaturesPerDB/Sqlserver.htm Adjust the connection string to connect to a SqlServerCE desktop database. This format is used to connect to the SQL Server catalog from which the LLBLGen Pro project was created. ```xml ``` -------------------------------- ### Constructing a Predicate Expression Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Filtering%20and%20Sorting/gencode_filteringbasics.htm Build a predicate expression that represents a WHERE clause with AND and OR conditions. This example demonstrates combining multiple conditions. ```csharp IPredicateExpression whereClause = ((Table1Fields.Foo == "One").And(Table1Fields.Bar == "Two")) .Or(Table2Fields.Bar2 == "Three"); ``` -------------------------------- ### Read All Entities into Collection (C#) Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Tutorials%20And%20Examples/examples_howdoi.htm Demonstrates three methods (Low-level API, Linq, QuerySpec) to fetch all entities of a given type into a collection using Adapter. ```csharp // Low-level API var allCustomers = new EntityCollection(); using(var adapter = new DataAccessAdapter()) { adapter.FetchEntityCollection(allCustomers, null); } // Linq EntityCollection allCustomers; using(var adapter = new DataAccessAdapter()) { var metaData = new LinqMetaData(adapter); allCustomers = metaData.Customer.Execute>(); } // QuerySpec var qf = new QueryFactory(); EntityCollection allCustomers; using(var adapter = new DataAccessAdapter()) { allCustomers = qf.Customer.FetchQuery(); } ``` ```csharp // Low-level API var allCustomers = new CustomerCollection(); allCustomers.GetMulti(null); // Linq var metaData = new LinqMetaData(); CustomerCollection allCustomers = metaData.Customer.Execute(); // QuerySpec var qf = new QueryFactory(); var allCustomers = new CustomerCollection(); allCustomers.GetMulti(qf.Customer); ``` -------------------------------- ### Instantiate Entity using Primary Key (Fetch Method) Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/SelfServicing/gencode_usingentityclasses_instantiating.htm Instantiate an empty entity object and then fetch its data using the FetchUsingPK method with the primary key value. ```C# var customer = new CustomerEntity(); customer.FetchUsingPK("CHOPS"); ``` -------------------------------- ### SQL Server Stored Procedure Example Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/SelfServicing/gencode_datareadersprojections.htm A SQL Server stored procedure that returns two resultsets based on a country parameter. ```sql CREATE procedure pr_CustomersAndOrdersOnCountry @country VARCHAR(50) AS SELECT * FROM Customers WHERE Country = @country SELECT * FROM Orders WHERE CustomerID IN ( SELECT CustomerID FROM Customers WHERE Country = @country ) ``` -------------------------------- ### Create and Save a New Customer Entity Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/SelfServicing/gencode_usingentityclasses_creating.htm Instantiate a new Customer entity, populate its fields with data, and then save it to the database using the Save() method. Fields not explicitly set will retain their default database values (e.g., NULL). ```csharp var customer = new CustomerEntity(); customer.CustomerID = "FOO"; customer.Address = "1, Bar drive"; customer.City = "Silicon Valey"; customer.CompanyName = "Foo Inc."; customer.ContactName = "John Coder"; customer.ContactTitle = "Owner"; customer.Country = "USA"; customer.Fax = "(604)555-1233"; customer.Phone = "(604)555-1234"; customer.PostalCode = "90211"; // save it customer.Save(); ``` -------------------------------- ### Configure LLBLGen Pro Runtime Framework Settings Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/using%20the%20generated%20code/gencode_runtimeconfiguration.htm Use this snippet in your application's startup code to configure connection strings, Data Query Engines (DQE), dependency injection, tracers, and entity-related settings. ```csharp // ... this code is placed in a method called at application startup RuntimeConfiguration.AddConnectionString("ConnectionString.SQL Server (SqlClient)", "data source=nerd;initial catalog=Northwind;integrated security=SSPI;persist security info=False;packet size=4096"); // Configure the DQE RuntimeConfiguration.ConfigureDQE( c => c.SetTraceLevel(TraceLevel.Verbose) .AddDbProviderFactory(typeof(System.Data.SqlClient.SqlClientFactory)) .SetDefaultCompatibilityLevel(SqlServerCompatibilityLevel.SqlServer2012)); // Configure Dependency Injection RuntimeConfiguration.SetDependencyInjectionInfo( new List() { typeof(AddressEntity).Assembly, this.GetType().Assembly }, new List() { "Northwind", "Authorizers", }); // Configure tracers RuntimeConfiguration.Tracing .SetTraceLevel("ORMPersistenceExecution", TraceLevel.Info) .SetTraceLevel("ORMPlainSQLQueryExecution", TraceLevel.Info); // Configure entity related settings RuntimeConfiguration.Entity .SetMarkSavedEntitiesAsFetched(true) .SetMakeInvalidFieldReadsFatal(true); ``` -------------------------------- ### FieldCompareValuePredicate Examples Source: https://www.llblgen.com/Documentation/5.13/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Filtering%20and%20Sorting/gencode_filteringpredicateclasses.htm Instantiate FieldCompareValuePredicate using ComparisonMethod or operator overloads. Use CaseInsensitive() for case-insensitive comparisons on databases with case-sensitive collations. ```csharp // SQL: EmployeeId = 2 var pred1 = OrderFields.EmployeeId.Equal(2); // SQL: EmployeeId <> 2 var pred2 = OrderFields.EmployeeId.NotEqual(2); // SQL, case insensitive comparison on Oracle: // UPPER(CompanyName)="FOO INC" var pred3 = CustomerFields.CompanyName.Equal("FOO INC") .CaseInsensitive(); ``` ```csharp // --------------- // above examples using operator overloads // SQL: EmployeeId = 2 var pred1 = OrderFields.EmployeeId==2; // SQL: EmployeeId <> 2 var pred2 = OrderFields.EmployeeId!=2; ``` ```csharp IPredicate p = CustomerFields.CompanyName.Equal("FOO INC").CaseInsensitive(); ```