Skip to content

Latest commit

 

History

History
291 lines (234 loc) · 9.51 KB

File metadata and controls

291 lines (234 loc) · 9.51 KB

Custom methods

Custom methods are platform independent queries that will be translated:

Load

Load methods allow you to define a method for loading sets of data.

This LoadByAvailable method on the Product entity:

LOAD(bool availability)
WHERE IsAvailable=@availability

Will be translated into this T-SQL stored procedure:

CREATE PROCEDURE [dbo].[Product_LoadByAvailable]
(
 @availability [bit],
 @_orderBy0 [nvarchar] (64) = NULL,
 @_orderByDirection0 [bit] = 0
)
AS
SET NOCOUNT ON
SELECT DISTINCT
    [Product].[Product_Id], 
    [Product].[Product_Price], 
    [Product].[Product_Name], 
    [Product].[Product_IsAvailable], 
    [Product].[_trackLastWriteTime], 
    [Product].[_trackCreationTime], 
    [Product].[_trackLastWriteUser], 
    [Product].[_trackCreationUser], 
    [Product].[_rowVersion] 
FROM [Product]
WHERE ([Product].[Product_IsAvailable] = @availability)

RETURN
GO

Since the generated method manipulates sets of entities the method is generated in the ProductCollection class:

[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, true)]
public static OrderProcess.Marketing.ProductCollection LoadByAvailable(bool availability)
{
    OrderProcess.Marketing.ProductCollection ret = OrderProcess.Marketing.ProductCollection.PageLoadByAvailable(int.MinValue, int.MaxValue, null, availability);
    return ret;
}


[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, true)]
public static OrderProcess.Marketing.ProductCollection PageLoadByAvailable(int pageIndex, int pageSize, CodeFluent.Runtime.PageOptions pageOptions, bool availability)
{
    if ((pageIndex < 0))
    {
        pageIndex = 0;
    }
    if ((pageSize < 0))
    {
        if ((pageOptions != null))
        {
            pageSize = pageOptions.DefaultPageSize;
        }
        else
        {
            pageSize = int.MaxValue;
        }
    }
    OrderProcess.Marketing.ProductCollection ret = new OrderProcess.Marketing.ProductCollection();
    System.Data.IDataReader reader = null;
    try
    {
        reader = OrderProcess.Marketing.ProductCollection.PageDataLoadByAvailable(pageOptions, availability);
        if ((reader == null))
        {
            return ret;
        }
        ret.LoadByAvailable(pageIndex, pageSize, pageOptions, reader, availability);
    }
    finally
    {
        if ((reader != null))
        {
            reader.Dispose();
        }
        CodeFluent.Runtime.CodeFluentPersistence.CompleteCommand(OrderProcess.Constants.OrderProcessStoreName);
    }
    return ret;
}

public static System.Data.IDataReader PageDataLoadByAvailable(CodeFluent.Runtime.PageOptions pageOptions, bool availability)
{
    CodeFluent.Runtime.CodeFluentPersistence persistence = CodeFluentContext.Get(OrderProcess.Constants.OrderProcessStoreName).Persistence;
    persistence.CreateStoredProcedureCommand(null, "Product", "LoadByAvailable");
    persistence.AddRawParameter("@availability", availability);
    if ((pageOptions != null))
    {
        System.Collections.IEnumerator enumerator = pageOptions.OrderByArguments.GetEnumerator();
        bool b;
        int index = 0;
        for (b = enumerator.MoveNext(); b; b = enumerator.MoveNext())
        {
            CodeFluent.Runtime.OrderByArgument argument = ((CodeFluent.Runtime.OrderByArgument)(enumerator.Current));
            persistence.AddParameter(string.Format("@_orderBy{0}", index), argument.Name);
            persistence.AddParameter(string.Format("@_orderByDirection{0}", index), ((int)(argument.Direction)));
            index = (index + 1);
        }
    }
    System.Data.IDataReader reader = CodeFluentContext.Get(OrderProcess.Constants.OrderProcessStoreName).Persistence.ExecuteReader();
    return reader;
}

private void LoadByAvailable(int pageIndex, int pageSize, CodeFluent.Runtime.PageOptions pageOptions, System.Data.IDataReader reader, bool availability)
{
    if ((reader == null))
    {
        throw new System.ArgumentNullException("reader");
    }
    if ((pageIndex < 0))
    {
        pageIndex = 0;
    }
    if ((pageSize < 0))
    {
        if ((pageOptions != null))
        {
            pageSize = pageOptions.DefaultPageSize;
        }
        else
        {
            pageSize = int.MaxValue;
        }
    }
    this.BaseList.Clear();
    this.BaseTable.Clear();
    int count = 0;
    int readCount = 0;
    bool readerRead;
    for (readerRead = reader.Read(); ((readerRead == true) 
                && ((count < this.MaxCount) 
                && (count < pageSize))); readerRead = reader.Read())
    {
        readCount = (readCount + 1);
        if ((CodeFluent.Runtime.CodeFluentPersistence.CanAddEntity(pageIndex, pageSize, pageOptions, readCount) == true))
        {
            OrderProcess.Marketing.Product product = new OrderProcess.Marketing.Product();
            ((CodeFluent.Runtime.ICodeFluentEntity)(product)).ReadRecord(reader);
            if ((this.BaseContains(product) == false))
            {
                this.BaseAdd(product);
                count = (count + 1);
            }
            product.EntityState = CodeFluent.Runtime.CodeFluentEntityState.Unchanged;
        }
    }
}

LoadOne

LoadOne methods allow you to define a platform independent query, loading a single line of data.

This LoadByName on an Employee entity:

LOADONE(string Name)
WHERE Name=@Name

Will generate this stored procedure:

CREATE PROCEDURE [dbo].[Employee_LoadByName]
(@Name [nvarchar] (256))
AS
SELECT DISTINCT [Employee].[Employee_Id], [Employee].[Employee_Name], ... FROM [Employee]
    WHERE ([Employee].[Employee_Name] = @Name)

And this method on the Employee C# class:

public static Employee LoadByName(string name)

Search

See the Search methods section.

Delete

Delete methods allow you to define custom query for deleting data.

This DeleteByName on an Employee entity:

DELETE(string Name)
WHERE Name STARTSWITH @Name

Looking at the generated stored procedures for the Employee entity, we can notice that there is a new stored procedure Employee_DeleteByName:

CREATE PROCEDURE [dbo].[Employee_DeleteByName] (@Name [nvarchar] (256))
AS
DELETE FROM [Employee] WHERE ([Employee].[Employee_Name] LIKE (@Name + '%'))

If we take a look at the generated code for the EmployeeCollection class, we can see that there is a new DeleteByName method.

public static void DeleteByName(string name)

Count

Count methods allow you to define a platform independent query, counting lines of data.

Since the generated method works on sets of entities, in the generated Business Object Model (BOM), the method is generated in the collection class.

Count methods are very similar to Load methods except that, instead of returning entities, they return an integer, as the result of the count operation.

This CountByCountry on an Employee entity:

COUNT(string countryName)
WHERE Address.Country LIKE @countryName

If we take a look at the generated stored procedures for the Employee entity, we can notice that there is a new stored procedure Employee_CountByCountry.

CREATE PROCEDURE [dbo].[Employee_CountByCountry] (@countryName [nvarchar] (256))
AS
SELECT COUNT(*) FROM [Employee]
    LEFT OUTER JOIN [Address] ON ([Employee].[Employee_Address_Id] = [Address].[Address_Id])
    WHERE ([Address].[Address_Country] LIKE @countryName)

Looking at the generated code for the EmployeeCollection class, we can see that there is a new CountByCountry method which returns an integer.

public static int CountByCountry(string countryName);

Snippets

Snippets are chunks of code that are declared in a CodeFluent model and injected in generated classes.

Two types of snippets are available in CodeFluent:

  • Snippets: entity level snippets,
  • SetSnippets: entity collection (a.k.a. set) level snippets.

Code Snippets are used to inject code chunks in standard generated classes.

Snippets have the following advantages:

  • snippets can be injected in all layers of the application automatically (e.g. business layer, service layer, etc.),
  • since snippets are declared in the model, they survive model generations,
  • snippets are practical because they use the programming languages we know: a snippet is coded in the targeted language directly since it will be copied and pasted as is in the generated code.

Add a method on you customer entity and choose snippet with method signature for the Entity class:

And write your business logic:

This will add some code directly into the generated Customer class:

// Snippet method 'GetName'
public string GetName()
{
    return _firstName + " " + _lastName;
}

Note: Another solution to extend the generated code is to use partial classes which is generally a good practice when involved snippets are actually big chunks of code.

In this case, we recommend the following convention: for an entity named MyEntity that is generated in the files MyEntity.cs and MyEntityCollection.cs, place the entity extra-code in the file MyEntity.Partial.cs and the entity collection extra-code in the file MyEntityCollection.Partial.cs.