Quantcast
Channel: DevExpress Support Center (Examples)
Viewing all 7205 articles
Browse latest View live

How to generate a sequential number for a business object within a database transaction

$
0
0

This is a general solution, showing how to use the ExplicitUnitOfWork class to generate sequential numbers that can then be used as user-friendly identifiers in documents, as invoice line numbers, etc. Here, as opposed to the solution shown in the How to make user-friendly object identifiers KB Article, the ExplicitUnitOfWork class is used to ensure that the assignment of the sequential number will be a part of a database transaction that results in the successful saving of the document.
Hence, the current solution will also work in a scenario with high-volume of concurrency transactions.

See also:
How to make user-friendly object identifiers
How to generate and assign a sequential number for a business object within a database transaction, while being a part of a successful saving process (XAF)


How to generate a sequential number for a persistent object within a database transaction (XAF)

$
0
0

This example illustrates one of the possible approaches to implementing an identifier field with sequential values. Alternate approaches are listed in the An overview of approaches to implementing a user-friendly sequential number for use with an XPO business class KB article.

Scenario

This is a variation of the How to generate and assign a sequential number for a business object within a database transaction, while being a part of a successful saving process XPO example, which was specially adapted for XAF applications.

In particular, for better reusability and more smooth integration with the standard XAF CRUD Controllers, all the required operations to generate sequences are managed within the base persistent class automatically when a persistent object is being saved. For more developer convenience, this solution is organized as a reusable XAF module - GenerateUserFriendlyId.Module. This module consists of several key parts:

    - Sequence and SequenceGenerator are auxiliary classes that take the main part in generating user-friendly identifiers. Take special note that the SequenceGenerator.Initialize method must be called during your XAF application startup for the correct operation.

    - UserFriendlyIdPersistentObject is a base persistent class that subscribes to XPO's Session events and delegates calls to the core classes above. Normally, you must inherit your own business classes from this base class to get the described functionality in your project.

    - IUserFriendlyIdDomainComponent is a base domain component that should be implemented by all domain components that require the described functionality.

Check the original example description first for more information on the demonstrated scenarios and functionality.




Steps to implement
1. Copy and include the GenerateUserFriendlyId.Module project into your solution and make sure it is built successfully.  Invoke the Module or Application Designer for the YourSolutionName.Module/Module.xx  or YourSolutionName.Wxx/WxxApplication.xx files by double-clicking it in Solution Explorer. Invoke the Toolbox (Alt+X+T) and then drag & drop the GenerateUserFriendlyIdModule component into the modules list on the left.

2. For apps with no security or with the Client-Side Security (XPObjectSpaceProvider or SecuredObjectSpaceProvider):
In the YourSolutionName.Wxx/WxxApplication.xx files, modify the CreateDefaultObjectSpaceProvider method to call the SequenceGenerator.Initialize method as shown in the Demo.Wxx\WxxApplication.xx files:

[C#]
...protectedoverridevoidCreateDefaultObjectSpaceProvider(CreateCustomObjectSpaceProviderEventArgsargs){GenerateUserFriendlyId.Module.Utils.SequenceGenerator.Initialize(this,args.ConnectionString);//!!!...}

For apps with the Middle Tier Security (DataServerObjectSpaceProvider):
In the YourSolutionName.ApplicationServer project, locate and modify the serverApplication_CreateCustomObjectSpaceProvider or CreateDefaultObjectSpaceProvider  methods to call the SequenceGenerator.Initialize method as shown below:

[C#]
privatestaticvoidserverApplication_CreateCustomObjectSpaceProvider(objectsender,CreateCustomObjectSpaceProviderEventArgse){GenerateUserFriendlyId.Module.SequenceGenerator.Initialize((XafApplication)sender,e.ConnectionString);

In the same code file, locate the serverApplication.Dispose(); line and move to the end of the Main or OnStop methods in the Console or Windows Service applications respectively (in the latter case, the "serverApplication" variable must also be declared in the higher scope).


3.
 If you are using pure XPO classes, then inherit your required business classes from the module's UserFriendlyIdPersistentObject one and use the derived SequenceNumber property as required:

[C#]
publicclassContact:GenerateUserFriendlyId.Module.BusinessObjects.UserFriendlyIdPersistentObject{[PersistentAlias("concat('C', ToStr(SequentialNumber))")]publicstringContactId{get{returnConvert.ToString(EvaluateAlias("ContactId"));}}

If you are using DC interfaces, then implement the IUserFriendlyIdDomainComponent interface by your custom domain component:

[C#]
publicinterfaceIDocument:GenerateUserFriendlyId.Module.BusinessObjects.IUserFriendlyIdDomainComponent{[Calculated("concat('D', ToStr(SequentialNumber))")]stringDocumentId{get;}

Additionally for DC, use the UserFriendlyIdPersistentObject as a base class during your custom domain component registration, e.g.:

[C#]
XafTypesInfo.Instance.RegisterEntity("Document",typeof(IDocument),typeof(GenerateUserFriendlyId.Module.BusinessObjects.UserFriendlyIdPersistentObject));

Note that the sequential number functionality shown in this example does not work with DC shared parts , because it requires a custom base class, which is not allowed for shared parts.

4. For more information, download and review the Address, Contact, and IDocument types within the Demo.Module project. These are test business objects that demonstrate the use of the described functionality for XPO and DC respectively. A required format for the user-friendly identifier property in these end classes is defined within an aliased property (ContactId in the example above) by concatenation of a required constant or dynamic value with the SequentialNumber property provided by the base UserFriendlyIdPersistentObject class. So, if you need to have a different format, modify the PersistentAliasAttribute expression as your business needs dictate.

 

IMPORTANT NOTES

1. As an alternative, you can implement much simpler solutions at the database level or by using the built-in DistributedIdGeneratorHelper.Generate method. Refer to the An overview of approaches to implementing a user-friendly sequential number for use with an XPO business class article for more details.

2.  In the Integrated Mode and middle-tier Application Server scenario the newly generated sequence number will appear in the DetailView only after a manual refresh (i.e., it will be empty right away after saving a new record), because the sequence is generated on the server side only and is not passed to the client. You can download a ready test project for these configurations here. See also the "Refresh the Identifier field value in UI" section in this KB article.
3. You can specify or seed the initial sequence value manually: either by editing the Sequence table in the database or using the standard XPO/XAF means by manipulating the Sequence objects, e.g.:

[C#]
using(IObjectSpaceos=Application.CreateObjectSpace(typeof(Sequence))){Sequencesequence=os.FindObject<Sequence>(CriteriaOperator.Parse("TypeName=?",typeof(E2829).FullName));sequence.NextSequence= 5;os.CommitChanges();}

See also:
How to create multiple sequences based on the a class property value, not one sequence per class type


Your feedback is needed!
We would greatly appreciate it if you share your feedback here in comments or rather participate in this short survey (~3 min).

Question Comments

Added By: Mr. Murat YILMAZ at: 10/7/2012 9:15:18 AM    

Thanks for the example. I developed ISequentialNumber domain component which based on this article and code. Now this sequential number functonatility shon in this example work with domain components and shared parts.

using System;
using System.Collections.Generic;
using System.ComponentModel;

using DevExpress.ExpressApp.DC;
using DevExpress.Persistent.Base;
using DevExpress.Xpo;
using DevExpress.Xpo.Metadata;
using DevExpress.ExpressApp;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation;

using MyWay.Xaf.Module;
using MyWay.Xaf.Utils.Sequence;

namespace MyWay.Xaf.Module
{
    [DomainComponent]
    [NavigationItem]
    public interface ISequentialNumber
    {
        #region PROPERTIES

        #region SequentialNo

        [Persistent]
        string SequentialNo
        {
            get;
        }

        #endregion SequentialNo

        #region SequentialNumber
        
        [System.ComponentModel.Browsable(false)]
        [Indexed(Unique = false)]
        long SequentialNumber
        {
            get ;
            set;
        }

        #endregion SequentialNumber

        #endregion PROPERTIES
    }

    [DomainLogic(typeof(ISequentialNumber))]
    public class ISequentialNumberLogic
    {

            public static string Get_SequentialNo(ISequentialNumber instance)
            {
                return "asd" + instance.SequentialNumber.ToString();
            }

            

        private static object syncRoot = new object();
        private static SequenceGenerator sequenceGenerator;

        #region METHODS

        #region PUBLIC METHODS

        #region GenerateSequence

        public static void GenerateSequence(ISequentialNumber instance)
        {
            lock (syncRoot)
            {
                Dictionary<string, bool> typeToExistsMap = new Dictionary<string, bool>();

                foreach (object item in ((XPBaseObject)instance).Session.GetObjectsToSave())
                {
                    typeToExistsMap[((XPBaseObject)instance).Session.GetClassInfo(item).FullName] = true;
                }

                if (sequenceGenerator == null)
                {
                    sequenceGenerator = new SequenceGenerator(typeToExistsMap);
                }

                SubscribeToEvents(((XPBaseObject)instance).Session);
                OnSequenceGenerated(sequenceGenerator.GetNextSequence(((XPBaseObject)instance).ClassInfo), instance);
            }
        }

        #endregion GenerateSequence

        #endregion PUBLIC METHODS

        #region PROTECTED METHODS

        #region OnSaving

        public static void OnSaving(ISequentialNumber instance)
        {
            try
            {
                //base.OnSaving();
                if (((XPBaseObject)instance).Session.IsNewObject(instance) && !typeof(NestedUnitOfWork).IsInstanceOfType(((XPBaseObject)instance).Session))
                {
                    GenerateSequence(instance);
                }
            }
            catch
            {
                CancelSequence(((XPBaseObject)instance).Session);
                throw;
            }
        }

        #endregion OnSaving

        #endregion PROTECTED METHODS

        #region INTERNAL METHODS

        #endregion INTERNAL METHODS

        #region PRIVATE METHODS

        #region AcceptSequence

        private static void AcceptSequence(Session session)
        {
            lock (syncRoot)
            {
                if (sequenceGenerator != null)
                {
                    try
                    {
                        sequenceGenerator.Accept();
                    }
                    finally
                    {
                        CancelSequence(session);
                    }
                }
            }
        }

        #endregion AcceptSequence

        #region CancelSequence

        private static void CancelSequence(Session session)
        {
            lock (syncRoot)
            {
                UnSubscribeFromEvents(session);
                if (sequenceGenerator != null)
                {
                    sequenceGenerator.Close();
                    sequenceGenerator = null;
                }
            }
        }

        #endregion CancelSequence

        #region Session_AfterCommitTransaction

        private static void Session_AfterCommitTransaction(object sender, SessionManipulationEventArgs e)
        {
            
            AcceptSequence(e.Session);
        }

        #endregion Session_AfterCommitTransaction

        #region Session_AfterRollBack

        private static void Session_AfterRollBack(object sender, SessionManipulationEventArgs e)
        {
            CancelSequence(e.Session);
        }

        #endregion Session_AfterRollBack

        #region Session_FailedCommitTransaction

        private static void Session_FailedCommitTransaction(object sender, SessionOperationFailEventArgs e)
        {
            CancelSequence((Session)sender);
        }

        #endregion Session_FailedCommitTransaction

        #region SubscribeToEvents

        private static void SubscribeToEvents(Session session)
        {
            if (!(session is NestedUnitOfWork))
            {
                session.AfterCommitTransaction += Session_AfterCommitTransaction;
                session.AfterRollbackTransaction += Session_AfterRollBack;
                session.FailedCommitTransaction += Session_FailedCommitTransaction;
            }
        }

        #endregion SubscribeToEvents

        #region UnSubscribeFromEvents

        private static void UnSubscribeFromEvents(Session session)
        {
            if (!(session is NestedUnitOfWork))
            {
                session.AfterCommitTransaction -= Session_AfterCommitTransaction;
                session.AfterRollbackTransaction -= Session_AfterRollBack;
                session.FailedCommitTransaction -= Session_FailedCommitTransaction;
            }
        }

        #endregion UnSubscribeFromEvents

        #region OnSequenceGenerated

        private static void OnSequenceGenerated(long newId, ISequentialNumber instance)
        {
            instance.SequentialNumber = newId;
        }

        #endregion OnSequenceGenerated

        #endregion PRIVATE METHODS

        #endregion METHODS
    }
}

Added By: Luis Alberto Santiago at: 2/25/2013 8:06:36 PM    

Hi Mr. Murat YILMAZ, Can yo provide some example to use the class. I am looking it for shared parts

Added By: Andrew Bingham 2 at: 7/8/2013 3:38:51 AM    

I implemented this OK in a Solution

When I eimplmented it in a different solution I got an Exception
"Message: Value cannot be null.
Parameter name: Application"

thrown at:

    public static void Initialize() {
            Guard.ArgumentNotNull(Application, "Application");

Added By: Dennis (DevExpress Support) at: 7/11/2013 3:11:06 AM    

@Andrew: You forgot to add the following code:

public override void Setup(XafApplication application) {
            base.Setup(application);
            SequenceGeneratorInitializer.Register(application);
        }

You will not experience this and similar difficulties if you simply add the reusable module into your solution as per instructions above.

Added By: Carlitos at: 8/23/2014 6:46:05 PM    

Hi,
Is this now supported in Middle-Tier XAF applications?

Thanks,

Carlitos

Added By: Dennis (DevExpress Support) at: 8/25/2014 4:38:12 AM    

We have not performed additional R&D and testing of this particular example in a middle-tier scenario. Moreover, I see technical problems using this particular solution in this configuration, because here we use ExplicitUnitOfWork, which implies that it will be a sole owner of the database connection. Probably, for this configuration, it is better to stick to a standard solution, e.g. using database triggers. 

Added By: Carlitos at: 8/25/2014 9:34:23 AM    

Hi Dennis,
But how does the Middle-tier handle database connections? I thought it would do some sort of connection pooling and manage all client connections?

Why do you think that Triggers are a good alternative?

Carlos

Added By: Dennis (DevExpress Support) at: 8/26/2014 6:14:27 AM    

By default, the middle-tier app server uses ThreadSafeDataLayer to effectively handle requests from multiple clients at the same time. Connection pooling may be used here, but this is not managed by us by default and is rather controller by ADO.NET transparently for a consumer. My main concern here was that in such a multi-user environment it will not be possible to exclusively lock the connection by one user.
A solution at the database level looks more universal as it works at the database level and is irrelevant to whether the app server is used or not. 

Added By: Vishwas Mokashi at: 4/14/2015 11:21:58 AM    

In XAF application I have about 25 various business objects that need to generate unique user friendly sequence numbers in when saved. For example Customer Number, Invoice Number, Order Number, etc. Many users are going to work concurrently and everything should work in transaction.

Which approach should I use, the one in E2620 or E2829?.

I felt E2620 a bit better as I need not to inherit my classes (25 of them) from  UserFriendlyIdPersistentObject as shown in E2829.  

But approach in E2829 is said to be primarily for XAF applications

Added By: Dennis (DevExpress Support) at: 4/15/2015 4:47:25 AM    

@Vishwas: Both E2620  and E2829 demonstrate the same solution using ExplicitUnitOfWork. E2829 is just a bit better integrated with the XAF infrastructure.
If you do not want to inherit from a common base class, I suggest you consider using How to generate a sequential and user-friendly identifier field within a business class, which is simpler to implement and provides similar capabilities without using ExplicitUnitOfWork.

Added By: Vishwas Mokashi at: 4/17/2015 6:54:45 AM    

OK thanks Dennis.

Will simpler approach in "How to generate a sequential and user-friendly identifier field within a business class" handle concurrent users creating same business objects properly?. We can assume about 25 Concurrent users for same business object, with SQL Server DB.

Some users will be accessing system over low banddwidth VPN internet connection. (for Sale Invoice object which needs to generate sequencial Invoice Numbers)

Added By: Dennis (DevExpress Support) at: 4/20/2015 7:58:16 AM    

@Vishwas: Yes, it will. The DistributedIdGeneratorHelper class tries to save a record and repeats its attempts several times until it reaches the maximum number or saves data completely. Check out the corresponding source code for more details on how this works.

    public static class DistributedIdGeneratorHelper {
        public const int MaxIdGenerationAttemptsCounter = 7;
        public static int Generate(IDataLayer idGeneratorDataLayer, string seqType, string serverPrefix) {
            for(int attempt = 1; ; ++attempt) {
                try {
                    using(Session generatorSession = new Session(idGeneratorDataLayer)) {
                        CriteriaOperator serverPrefixCriteria;
                        if(serverPrefix == null) {
                            serverPrefixCriteria = new NullOperator("Prefix");
                        }
                        else {
                            serverPrefixCriteria = new BinaryOperator("Prefix", serverPrefix);
                        }
                        OidGenerator generator = generatorSession.FindObject<OidGenerator>(
                            new GroupOperator(new BinaryOperator("Type", seqType), serverPrefixCriteria));
                        if(generator == null) {
                            generator = new OidGenerator(generatorSession);
                            generator.Type = seqType;
                            generator.Prefix = serverPrefix;
                        }
                        generator.Oid++;
                        generator.Save();
                        return generator.Oid;
                    }
                }
                catch(LockingException) {
                    if(attempt >= MaxIdGenerationAttemptsCounter)
                        throw;
                }
            }
        }Added By: Vishwas Mokashi at: 4/21/2015 6:03:28 AM    

Thanks Dennis

Added By: Konstantin B (DevExpress) at: 12/4/2017 1:20:01 AM    Update: This example illustrates one of the possible approaches to implementing an identifier field with sequential values. Alternate approaches are listed in the An overview of approaches to implementing a user-friendly sequential number for use with an XPO business class KB article.

How to prevent a DetailView from being shown for a ListView record

$
0
0

Scenario

For certain data forms, a developer needs to limit end-users to editing only through the ListView, i.e. without invoking a separate DetailView.  This is usually done by activating the inline editing and MasterDetailMode = ListViewAndDetailView features as described at eXpressApp Framework > Concepts > UI Construction > Views > List View Edit Modes. More real user scenarios are described in this Support Center thread.


For more convenience and flexibility, the following Model Editor extensions are implemented in the example to control this behavior:
 - The DefaultShowDetailViewFromListView  attribute at the Views node level allows you to control this functionality globally per application via the Model Editor;
 - The ShowDetailView attribute at the Views | ListView node level allows you to customize only certain List Views via the Model Editor;




Steps to implement

1. Copy the WinWebSolution.Module\ShowDetailViewFromListViewController.xx file into the YourSolutionName.Module project and rebuild it.

Note: The process of opening a DetailView by double clicking/pressing the Enter key on a record selected in a ListView is managed by the standard DevExpress.ExpressApp.SystemModule.ListViewProcessCurrentObjectController class and its ProcessCurrentObjectAction in particular. So, we can disable this Action to accomplish our task. The approaches from the eXpressApp Framework > Concepts > Application Model > Extend and Customize the Application Model in Code,  eXpressApp Framework > Concepts > Application Model > Access the Application Model in Code and ActionBase.Enabled Property articles will be used here.

2. For testing purposes, invoke the Model Editor and set the DefaultShowDetailViewFromListView or ShowDetailView properties for the Views or Views | YourObjetType_ListView nodes to False and run the test app to see that a required ListView no longer opens a DetailView in the aforementioned scenario.

IMPORTANT NOTES
This article covers only the case when a DetailView is shown from the ListView after a User double clicks/presses the enter key on a record. Other scenarios should be handled separately by extending the code of this controller. For example, if you do not want to show a DetailView after a new object is created via the New Action, you can handle the NewObjectViewController.ObjectCreating event and set its ObjectCreatingEventArgs.ShowDetailView property to False. However, this is outside the purpose of this article.

Question Comments

Added By: John01 at: 12/2/2015 6:18:00 PM    

This is such as useful feature that it should be part of standard XAF.

Added By: Dennis (DevExpress Support) at: 12/2/2015 11:48:15 PM    Thanks for your feedback. Our team will take it into account (S34026).Added By: Peter Kieslinger at: 12/19/2017 10:15:01 AM    Hi Dennis,

I tried this solution in web without success.
How can this be done in web?

My current Xaf version is 17.2.3
Added By: Michael (DevExpress Support) at: 12/20/2017 6:02:40 AM    @Peter: I just tested the Web part of this example with the current version of our libraries (17.2.4) and can confirm that the solution works as expected. If you have difficulty implementing it in your project, please submit a new ticket and attach the project demonstrating your attempts.

How to customize the underlying database provider options and data access behavior in XAF

$
0
0

IMPORTANT NOTE

This article describes some advanced customization techniques and low-level entities of the framework with regard to data access, which may be required in complex scenarios only.
So, if you just want to change the connection string, e.g. to use the Oracle instead of the Microsoft SQL Server database, then you would better refer to the Connect an XAF Application to a Database Provider article and documentation on your database provider instead. The XAF integration of supported ORM libraries is also described in the Business Model Design section of the framework's documentation.


Introducing IObjectSpaceProvider and IObjectSpace
XAF accesses data from a data store through special abstractions called - IObjectSpaceProvider and IObjectSpace.
The IObjectSpace is an abstraction above the ORM-specific database context (e.g., the DBContext used in Entity Framework or the Session in XPO) allowing you to query or modify data.
The IObjectSpaceProvider is a provider/creator of IObjectSpace entities, which also manages which business types these IObjectSpace are supposed to work with, how to set up the underlying connection to the database, create and update it and other low level data access options.



An XafApplication can use one or several IObjectSpaceProvider objects at the same time, and you can access this information through the XafApplication.ObjectSpaceProvder or XafApplication.ObjectSpaceProviders properties. Check out these help links to learn more on how to plug in custom IObjectSpaceProvider objects a well.

There are several built-in implementations of the IObjectSpaceProvider and IObjectSpace interfaces in our framework, which are usually specific to a target ORM (Entity Framework or XPO). I suggest you check out the source code of the default framework classes to better understand the role of the IObjectSpaceProvider:

...\DevExpress.ExpressApp.Xpo\XPObjectSpaceProvider.cs
...\DevExpress.ExpressApp.EF\EFObjectSpaceProvider.cs 

Typical customization considerations
You may want to provide a fully custom IObjectSpaceProvider implementation or inherit from the built-in implementors when you want to customize how data access is performed for a chosen ORM.
Below is a list of typical scenarios where a custom IObjectSpaceProvider may be required:

1. How to use XPO caching in XAF 
2. How to prevent altering the legacy database schema when creating an XAF application 
3. How to connect to remote data store and configure WCF end point programmatically 
4. How do I map persistent classes to another schema, e.g. other than the default "dbo" in MS SQL Server?
5. How to use a custom ObjectSpace throughout the application by handling the CreateCustomObjectSpaceProvider event? 
6. How to connect different ORM data models to several databases within a single application
7. How to customize the Object Space behavior in XPO-based XAF applications
8. How to customize the UnitOfWork behavior in XPO-based XAF applications

In most cases, it is not required to implement the IObjectSpaceProvider interface from scratch since you can inherit from existing implementors or customize/just their parts.


XPO-specific customizations

1. Implementing IXpoDataStoreProvider

For instance, in XPO one of such replaceable parts is the IXpoDataStoreProvider interface, which enables you to provide a custom or configured IDataStore object, which is used for underlying data access with this ORM:

[C#]
publicinterfaceIXpoDataStoreProvider{IDataStoreCreateWorkingStore(outIDisposable[]disposableObjects);IDataStoreCreateUpdatingStore(outIDisposable[]disposableObjects);IDataStoreCreateSchemaCheckingStore(outIDisposable[]disposableObjects);stringConnectionString{get;}}

 

In its turn, XAF provides several ready to use implementations of this interface for most popular scenarios: 

1. ConnectionDataStoreProvider - can provide IDataStore by the IDbConnection object;

2. ConnectionStringDataStoreProvider - can provide IDataStore by just connecting string information;

3. MemoryDataStoreProvider - DataSet based in-memory IDataStore providers.


Technically, such an IXpoDataStoreProvider part is passed into the XPObjectSpaceProvider constructor as a parameter, which means that you can just customize it instead of re-implementing the whole XPObjectSpaceProvider logic:

[C#]
//In your XafApplication descendant class (e.g., in the YourSolutionName.Win/WinApplication.cs file).protectedoverridevoidCreateDefaultObjectSpaceProvider(CreateCustomObjectSpaceProviderEventArgsargs){args.ObjectSpaceProvider=newXPObjectSpaceProvider(newMyIXpoDataStoreProvider(args.ConnectionString,args.Connection,false),true);args.ObjectSpaceProviders.Add(newNonPersistentObjectSpaceProvider(TypesInfo,null));}

You can find IXpoDataStoreProvider implementation examples in the following articles:
How to use XPO caching in XAF
How to prevent altering the legacy database schema when creating an XAF application

Refer to the ...\DevExpress.ExpressApp.Xpo\XPObjectSpaceProvider.cs file within the XAF source code to better understand the role of this part.

2. Handling the DataStoreCreated event of ConnectionDataStoreProvider and ConnectionStringDataStoreProvider 
Instead of creating your own IXpoDataStoreProvider  from scratch, it is often simpler to explicitly create a ConnectionDataStoreProvider or ConnectionStringDataStoreProvider instance (an IXpoDataStoreProvider implementer) and subscribe to its DataStoreCreated event (available starting with version 17.2).  The event arguments (DataStoreCreatedEventArgs) expose the DataStore and Destination parameters that provide access to the current data store and its type (SchemaChecking,  Updating or Working). Refer to the How do I map persistent classes to another schema, e.g. other than the default "dbo" in MS SQL Server?  example for more details.

 

3. Overriding XPO connection or database providers

To learn more on this approach, check out the Database Systems Supported by XPO help topic and How to create a custom XPO connection provider and then use it in an XAF application article in particular.  To learn more on customizing data access settings for XPO, please refer to the corresponding product documentation: Data Access Layer.



See Also:
Can I connect an XAF application to a custom data source (Web service, OData service, NoSQL database, etc.)?

T590896: How to customize the Object Space behavior in XPO-based XAF applications
T591324: How to customize the UnitOfWork behavior in XPO-based XAF applications

Question Comments

Added By: Rejoice Supsup at: 9/16/2015 11:33:05 AM    

Is this intended to contain an empty example resource?

Added By: Dennis (DevExpress Support) at: 9/16/2015 11:46:15 AM    

Yes. This article originally contained an example, but it is now more like a KB article.

Added By: Rejoice Supsup at: 9/16/2015 12:00:10 PM    

Thank you for the quick reply. But I thought this might be misleading since it's categorized as an example. Should I expect that you're be providing an example in the future? If I may suggest, what about 2 databases:

#1 - Departments and Employees
#2 - Customers and Orders

Where #1 is integrated with the Security Module and #2 (used by XAF Win Forms) to manage CRM data but will be authenticated via DB #1.

Added By: Dennis (DevExpress Support) at: 9/16/2015 12:16:34 PM    

The category is to be changed in the future as the main purpose of this article is to describe the main concepts.
There are already multiple examples mentioned in this article - see under the "Typical customization considerations" section (no plans for new examples so far). I hope you find them helpful to implement your particular scenario. Should you have any further difficulties with your own implementation, please submit a separate ticket and attach your sample showing what you tried to do and what did not work as expected. Thanks.

How to show ASPxPopupControl with detail ASPxDataView via button in grid's DataRowTemplate

$
0
0

This demo illustrates how to implement a Master-Detail relationship. The ASPxGridView control (master) contains an ASPxButton control inside the DataRowTempate. When a focus moves to the ASPxButton, the ASPxPopupControl with the ASPxDataView control (details) is shown. The ASPxDataControl is refreshed via a callback of the ASPxCallbackPanel control, which contains this ASPxDataView control.

Question Comments

Added By: (no info) at: 8/22/2012 4:12:47 AM    

What if the popup is useing contentUrl to open another page?

How to use timestamp to check for data conflicts when updating data via LinqDataSource

$
0
0

This demo is based on the Using a Timestamp with the LinqDataSource Control to Check Data Integrity MSDN article. It illustrates how to use a timestamp to check for data conflicts when updating data via a LinqDataSource control.

The LinqDataSource control stores the timestamp value on the Web page. When a user updates or deletes data, the LinqDataSource control checks the timestamp value against the current timestamp value in the database. If the LinqDataSource control detects that the value in the timestamp column has changed, the control does not update or delete a record. In this case, the record has been changed by another process. Instead, the LinqDataSource control raises an exception that indicates that the record has changed.

A timestamp column is automatically updated by SQL Server every time a record is modified. For more information, see Timestamp (Transact-SQL).

[SQL]
CREATE TABLE DemoTable( ... [TimeStamp] timestamp NOT NULL, ... )
[C#]
...[Column(Storage="_TimeStamp",...UpdateCheck=UpdateCheck.Always)]publicSystem.Data.Linq.BinaryTimeStamp{...}
[VB.NET]
...<Column(Storage:="_TimeStamp", ... UpdateCheck:=UpdateCheck.Always)> _PublicProperty TimeStamp() As System.Data.Linq.Binary ... EndProperty

The column's attribute UpdateCheck=UpdateCheck.Always means that records should be always tested for concurrency conflicts.

See Also:
Optimistic Concurrency Overview (LINQ to SQL)

How to trace process of dragging grid columns to Customization Window and within Header

How to specify built-in and Custom Command Buttons’ properties based on custom criteria

$
0
0

The example demonstrates how to specify the CommandButtons and Custom CommandButtons properties by handling the CommandButtonInitialize and CustomButtonInitialize events. The DataRows' VisibleIndex property and criteria set based on field values are used to determine the buttons' visibility.

Question Comments

Added By: Hans Leonhardt at: 11/16/2013 9:27:49 AM    

Just as an addition:
If you're Using an Entity e.g. an EntityDatasource this fails. This will work, e.g.

 Private Function DeleteButtonVisibleCriteria(ByVal grid As ASPxGridView, ByVal visibleIndex As Integer) As Boolean
  
     Dim row As NameOfYOurEntity = ASPxGridView1.GetRow(visibleIndex)
       ' e.g: The Entity has a boolean Property named "isAdmin"
     Return row.isAdmin
   
 End Function

Added By: Jean-Luc Praz at: 11/17/2014 6:24:59 AM    

Is there a way to find out if a row is the first or last row in a Grid ? I need to hide a button based on that criteria ?

Added By: Alessandro (DevExpress Support) at: 11/17/2014 7:47:58 AM    Hi,

I will create a separate ticket on your behalf to keep this web page simple: ASPxGridView - E3028 - Check row location. Thank you for your time and cooperation in advance.

Added By: Annette V at: 7/27/2015 1:45:16 AM    

Hello,
it's a pity, that your examples modified in 2014 is not running in VS 2013, because the example produces the message "The 'Microsoft.Jet.OLEDB.4.0' provider is not registered on the local machine".
I don't want to change my system for that problem.

Added By: Mike (DevExpress Support) at: 7/27/2015 4:30:49 AM    

Hello Annette,

To process your recent post more efficiently, I created a separate ticket on your behalf: T271600: How to use AccessDataSource / Microsoft.Jet.OLEDB.4.0 with VS 2013. This ticket is currently in our processing queue. Our team will address it as soon as we have any updates.


How to apply Bootstrap Form (form-control, btn) style to DevExpress editors in Native mode

$
0
0
This example illustrates how to enable the Native rendering mode (by setting the Native property to True) in order to produce the raw HTML elements and apply the Bootstrap Form (form-control, btn, etc.) style.
There is also a side-by-side comparison with the same set if editors in the DevExprss Moderno theme (applied in the Web.config) that has a similar color schema as the Bootstrap.

The main requirement is to set the editor's Native property in order to produce the raw HTML rendering and apply the Bootstrap style via the CssClass property:

[C#]
@Html.DevExpress().TextBox(settings=>{...settings.ControlStyle.CssClass="form-control";settings.Properties.Native=true;}).GetHtml()@Html.DevExpress().Memo(settings=>{...settings.ControlStyle.CssClass="form-control";settings.Properties.Native=true;}).GetHtml()@Html.DevExpress().Button(settings=>{...settings.ControlStyle.CssClass="btn btn-primary";settings.Styles.Native=true;}).GetHtml()

Optionally, it may be necessary to specify the editor's Width and Height dimensions (in percent or pixels) in order to achieve a consistent/custom layout.

WebForms Version:
How to apply a Bootstrap Form (form-control, btn, etc.) style to the DevExpress editors in Native mode

How to sort ASPxGridView by ASPxTextBox's value in UnboundColumn's DataItemTemplate

How to perform export of ASPxGridView in Ajax Update Panel using WriteToResponse technique

How to render CallbackPanel content inside SetContent method by using custom PartialView

$
0
0

It is possible to define a custom PartialView, which should be rendered via the Html.Partial method inside the SetContent method.

See Also:
CallbackPanel (Razor View engine) - How to render a required content in the Response directly inside the SetContent method via the ViewContext.Writer

Question Comments

Added By: Lubomir Kovac at: 2/18/2013 8:18:21 AM    

Hi,

I was trying to use this example, but I couldn't make it to run. The problem was in Html.Partial("DetailPartial").ToHtmlString() ... nothing worked. Than I found an example in http://www.devexpress.com/Support/Center/p/Q380845.aspx where @Html.RenderPartial("DetailPartial") is used.

I don't see any problem in my code - almost the same as here. Is this really working in 12.2.6?

thanks
Lubomir

How to keep selection in detail grids when paging master grid within SelectionCheckbox

How to export HtmlEditor content via built-in toolbar button and via custom action button

$
0
0

This example is standalone implementation of the online HTML Editor - Import/Export demo.
It illustrates how to export the HtmlEditor's content to several rich text formats via a built-in toolbar item and custom Controller Action.

How to apply Bootstrap Form (form-control, btn) style to DevExpress editors in Native mode

$
0
0
This example illustrates how to enable the Native rendering mode (by setting the Native property to True) in order to produce the raw HTML elements and apply the Bootstrap Form (form-control, btn, etc.) style.
There is also a side-by-side comparison with the same set if editors in the DevExprss Moderno theme (applied in the Web.config) that has a similar color schema as the Bootstrap.

The main requirement is to set the editor's Native property in order to produce the raw HTML rendering and apply the Bootstrap style via the CssClass property:

[ASPx]
<dx:ASPxTextBox...Native="true"CssClass="form-control"></dx:ASPxTextBox><dx:ASPxMemo...Native="true"CssClass="form-control"></dx:ASPxMemo><dx:ASPxButton...Native="true"CssClass="btn btn-primary"></dx:ASPxButton>

Optionally, it may be necessary to specify the editor's Width and Height dimensions (in percent or pixels) in order to achieve a consistent/custom layout.

MVC Version:
How to apply a Bootstrap Form (form-control, btn, etc.) style to the DevExpress editors in Native mode

How to bind ASPxGridView based on other grid's Selection and its UnboundColumn data

$
0
0

This example is based on the How to sort the ASPxGridView by the value of the ASPxTextBox control in the UnboundColumn's DataItemTemplate example. It illustrates how to bind the ASPxGridView control based on BoundColumns' and UnboundColumns' values of other ASPxGridView's Selection.

The UnboundColumns' values are stored in the Session variable, are updated via the ASPxCallback control, and represent a Dictionary object.

See Also:
How to sort the ASPxGridView by the value of the ASPxTextBox control in the UnboundColumn's DataItemTemplate

How to send asynchronous request using jQuery.ajax to retrieve values from large database

$
0
0

Compared to ASP.NET WebForms applications, in MVC, it is not necessary to bind controls each time you need to retrieve small portions of data from the database server. The example demonstrates how to use the jQuery.ajax method to request appropriate values from a SQL database.
The GridView extension also works in Server Mode.

How to adjust DevExpress ASP.NET controls when opening page in IE Compatibility Mode

How to adjust DevExpress ASP.NET MVC extensions when opening page in IE Compatibility Mode

How to use grid (with vertical scrollbar) in Full Screen mode (100% Width and Height)

$
0
0

This example demonstrates how to resize the ASPxGridView control based on the browser window size.

Update:
To keep the visual grid's size intact while adjusting it on the first load, wrap ASPxGridView with a hidden container and show it only after its full initialization and adjustment. For example:

[ASPx]
<divid="gridContainer"style="visibility: hidden"><dx:ASPxGridViewrunat="server"ID="gridView"...> ...</dx:ASPxGridView></div>
[JavaScript]
function OnInit(s, e){ AdjustSize(); document.getElementById("gridContainer").style.visibility = "";}

See Also:

How to use the ASPxPageControl control in a Full Screen mode (100% browser Width and Height)

Question Comments

Added By: neuDev33 at: 5/16/2012 11:48:45 AM    

I'm copy + pasting this code, but the height does not increase to cover the parent control

Added By: just wqq at: 9/18/2012 7:45:13 PM    

DevExpress.Web.ASPxGridView.v8.3 can do this

Added By: Michelle Young at: 7/31/2013 7:46:42 AM    

Visual studio says the code behind method is obsolete and you should now use RegisterBaseScript instead.

Added By: Yevgeniy Reznik at: 7/31/2013 8:45:41 PM    

Can you please update to the latest version of DevExpress?

Added By: Honesto Manlig at: 5/28/2014 9:03:24 PM    

How can I have the columns to be of width they need to be. Except for the last column to be the only one that grows to fill the rest of the gridview. For example, if there's three columns, if first column contains  text, it'll get as wide as it needs to so it does not wrap the text, then second column is a checkbox, so can always be same width, then the last column must get wide enough so that it fills the rest of the grid's width.

Added By: Artem (DevExpress Support) at: 5/29/2014 12:01:42 AM    Hello,

I've moved your question to a separate thread created on your behalf:
How to use the ASPxGridView control (with the enabled vertical scrollbar) in a Full Screen mode (100% browser Width and Height)
Please refer to it for further correspondence.Added By: Satarupa Brahma 1 at: 3/8/2016 10:37:29 AM    It is important to note that the ClientInstanceName needs to be set so that the java script can find the control that needs to be resized.   I struggled with this for several hours before I found the key.Added By: Jonathan Kent at: 9/7/2017 5:05:55 AM    When trying to implement this resolution using Razor it worked fine but I experienced a javascript error when my gridview was editable when clicking on add or update. To resolve the issue I removed all javascript and simply added this line to my gridview implentation;
settings.ClientSideEvents.Init = "function OnInit(s, e) {myGridViewName.SetHeight(Math.max(0, document.documentElement.clientHeight));}";
Added By: Larry (DevExpress Support) at: 9/7/2017 5:28:31 AM    

Hello Jonathan,

Thank you for providing your solution. I believe it may be helpful to other users.

Added By: Patrik Johansson _ at: 11/18/2017 9:05:40 AM    This ticket claims to set widht and height but I can see no code that actually sets the width? Also, I still find it strange that such an obvious feature as to resize the popup window for a very mature control like the ASPxGridView should require this much manual coding even in 2017. Added By: Vova (DevExpress Support) at: 11/20/2017 1:44:43 AM    Hello Patrik,

The Width property is specified in this example. Since it's set to "100%", ASPxGridView occupy all the available space inside its parent container.

Regards,
Vova
Viewing all 7205 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>