Wednesday, April 11, 2018

Access XAF Application Data in a non-XAF Application

Access XAF Application Data in a non-XAF Application

In certain scenarios, you may need to create an axillary application for database maintenance and use Object Space to query your primary XAF application data. This topic describes how you can create and use Object Space in a regular non-XAF application.
Important
We do not recommend using the approach described here in XAF applications. Instead, always use the XafApplication.CreateObjectSpace method or access an existing Object Space.
In a non-XAF application, you have no XafApplication object to create an Object Space. But, an XafApplication does not create Object Spaces itself. Internally, it uses the Object Space Provider designed to create Object Spaces for the currently used ORM and those registered in its overridden XafApplication.CreateDefaultObjectSpaceProvider method. In a non-XAF application, you can instantiate the Object Space Provider manually. In XPO-based applications, use the DevExpress.ExpressApp.Xpo.XPObjectSpaceProvider constructor for this purpose. In Entity Framework applications, use the DevExpress.ExpressApp.EF.EFObjectSpaceProvider. Then, you can call the provider's CreateObjectSpace method to create an Object Space.

Expanded Entity Framework Example

You can use the following code to access data of the EFDemo application (typically installed to %PUBLIC%\Documents\DevExpress Demos 17.2\Components\eXpressApp Framework\EFDemoCodeFirst) and write the list of Departments to the standard output stream.
C#
VB
using DevExpress.ExpressApp.EF;
using DevExpress.ExpressApp;
using EFDemo.Module.Data;
// ... 
class Program {
    static void Main(string[] args) {
        EFObjectSpaceProvider osProvider = new EFObjectSpaceProvider(typeof(EFDemoDbContext),
            "integrated security=True;multipleactiveresultsets=True;data source=(localdb)\\v11.0;initial catalog=EFDemo_17.2");
        IObjectSpace objectSpace = osProvider.CreateObjectSpace();
        foreach (Department department in objectSpace.GetObjects()) {
           Console.WriteLine(department.Title + "\t" + department.Office);
        }
    }
}

Expanded XPO Example

In XPO-based applications, you should additionally initialize the Types Info Subsystem. The following example demonstrates how to access data of the MainDemo application (typically installed to %PUBLIC%\Documents\DevExpress Demos 17.2\Components\eXpressApp Framework\MainDemo) and write the list of Departments to the standard output stream:
C#
VB
using DevExpress.ExpressApp.Xpo;
using DevExpress.ExpressApp;
using MainDemo.Module.BusinessObjects;
// ... 
class Program {
    static void Main(string[] args) {
        XpoTypesInfoHelper.GetXpoTypeInfoSource();
        XafTypesInfo.Instance.RegisterEntity(typeof(Department));
        XPObjectSpaceProvider osProvider = new XPObjectSpaceProvider(
        @"integrated security=SSPI;pooling=false;data source=(localdb)\v11.0;initial catalog=MainDemo_17.2", null);
        IObjectSpace objectSpace = osProvider.CreateObjectSpace();
        foreach (Department department in objectSpace.GetObjects()) {
            Console.WriteLine(department.Title + "\t" + department.Office);
        }
    }
}
If you need to populate the database with initial data, use the DatabaseUpdater.Update method as follows:
C#
VB
using DevExpress.ExpressApp.Updating;
// ... 
DatabaseUpdater databaseUpdater = new DatabaseUpdater(
    osProvider, new ModuleBase[0], "", osProvider.ModuleInfoType);
databaseUpdater.Update();

Expanded See Also

XAF implement Business Logic using ObjectSpace

Ways to Implement Business Logic

There are two common places for your business logic code - Controllers and business classes themselves. In Controllers, you can declare new and customize existing Actions and handle other Controllers' events. In business classes, you can put logic into property getters and setters, implement methods that are triggered automatically when the object is created, loaded, saved and deleted (see IXafEntityObject) and declare action methods. In these cases, Object Space is required when data the current business object exposes is insufficient for your business logic, and you need to query more data. You may also use Object Space in your database initialization code, in complex View Items, etc. This topic describes the API you can use to get Object Space in various contexts.

Expanded Get an Existing Object Space

Usually, you can use an existing Object Space instance accessible via the XAF API. The following table describes how you can get an Object Space from various contexts of your code:
ContextWays to Access Object SpaceExamples
Business Object
An Object Space reference is automatically assigned to the IObjectSpaceLink.ObjectSpace property when a business object supporting an IObjectSpaceLink is instantiated. You can implement this interface and access other business objects directly in the current object code using the Object Space passed to the ObjectSpace property.
If you additionally implement an IXafEntityObject, then you can place your logic into the IXafEntityObject.OnCreatedIXafEntityObject.OnLoaded and IXafEntityObject.OnSaving methods. You can use the XAF Business Object | EF Business Object from Template Gallery to add a class that supports both IXafEntityObject and IObjectSpaceLink.
We recommend using Controllers instead of accessing UI-related entities (ViewsControllersActions) and executing UI-specific logic within the business class code, because it violates the separation of concerns principle and is against the MVC architecture.
Controller
In XAF applications, an Object Space is automatically assigned for each View. In a View Controller, you can get the current View using the ViewController.View property. Then, access the Object Space with the View.ObjectSpace. You can also use the protected ViewController.ObjectSpace property that refers to the same Object Space as View.ObjectSpace.
A Window Controller does not expose a View directly. You can access the current Frame using the Controller.Frame property and get the View with Frame.View.
A View handles Object Space events to update the UI each time an object changes. We recommend creating a new Object Space that is not bound to a current View instead of using theView.ObjectSpace property to process large amounts of data. You should also use a new Object Space when you create a new View with the XafApplication.CreateListView or XafApplication.CreateDetailView methods.
Module Updater
In a ModuleUpdater descendant, you can use the protected ModuleUpdater.ObjectSpace property to access the Object Space instance that can be used for database update operations. Do not use a new Object Space to update the database.
List Editor
A reference to the CollectionSourceBase object is automatically passed to the IComplexListEditor.Setup method if your custom List Editor supports the IComplexListEditor interface. You can implement this interface and access the Object Space via the CollectionSourceBase.ObjectSpace property.
View Item or Property Editor
A reference to an Object Space is automatically passed to the IComplexViewItem.Setup method if your custom View Item or Property Editor supports the IComplexViewItem interface. You can implement this interface and store the Object Space reference to a local variable for future use.
Object Space is also available using arguments passed to various events of the XafApplication class.

Expanded Create a New Object Space

It is often necessary to instantiate a new Object Space (for example, when you create a View using the XafApplication.CreateListView or XafApplication.CreateDetailView methods). Use the XafApplication.CreateObjectSpace method instead of an Object Space constructor to create an Object Space. For instance, the Controller.Application property is available in a Controller context, and you can create an Object Space as follows:
C#
VB
IObjectSpace objectSpace = this.Application.CreateObjectSpace();
Refer to the XafApplication class description to see how to obtain an XafApplication instance in various contexts. You cannot create new Object Spaces in the business object context because an XafApplication instance is not available there.
Examples:
Important
You should manually dispose of an Object Space when you are finished using it if you do not assign it to a View. An Object Space associated with a View is removed automatically together with this View.
Once you have obtained or created an Object Space, you can use it to query or modify data (see Create, Read, Update and Delete Data).

Expanded See Also

ObjectSpace CRUD

Create, Read, Update and Delete Data

Once you have obtained or created an Object Space instance (as described in the Ways to Implement Business Logic topic), you can use it to create, read, update or delete data. This topic lists common data-aware operations with the corresponding Object Space methods and events.
Data Manipulation
Related IObjectSpace Members
Create a new object
Methods:
Get a single object
Methods:
Get a collection
Methods:
Count objects
Methods:
Save
Methods:
Properties:
Events:
Delete
Methods:
Properties:
Events:
Track modifications
Methods:
Properties:
Events:
Refresh and rollback
Methods:
Events:
For details, refer to the descriptions of these members.

Expanded See Also

Friday, April 6, 2018

XAF BO Template






Table Annotation



Default field


        [XafDisplayName("备注")]
        [MaxLength(255)]
        public string Remark { get; set; }

        [XafDisplayName("创立日期")]
        public DateTime? CreatedOn { get; set; }
        [XafDisplayName("创立人")]
        public PermissionPolicyUser CreatedBy { get; set; }
        [XafDisplayName("更新日期")]
        public DateTime? UpdatedOn { get; set; }
        [XafDisplayName("更新人")]
        public PermissionPolicyUser UpdatedBy { get; set; }

Master-Detail (One to many)

Master

        public IM_Request()
        {
            IM_RequestFiles = new List();
        }

        [DevExpress.ExpressApp.DC.Aggregated]
        public virtual IList IM_RequestFiles { get; set; }

Detail


        public virtual IM_Request IM_Request { get; set; }





Thursday, March 29, 2018

Programming Concepts (C#)

Programming Concepts (C#)

This section explains programming concepts in the C# language.

In This Section

TitleDescription
Assemblies and the Global Assembly Cache (C#)Describes how to create and use assemblies.
Asynchronous Programming with async and await (C#)Describes how to write asynchronous solutions by using the async and awaitkeywords in C#. Includes a walkthrough.
Attributes (C#)Discusses how to provide additional information about programming elements such as types, fields, methods, and properties by using attributes.
Caller Information (C#)Describes how to obtain information about the caller of a method. This information includes the file path and the line number of the source code and the member name of the caller.
Collections (C#)Describes some of the types of collections provided by the .NET Framework. Demonstrates how to use simple collections and collections of key/value pairs.
Covariance and Contravariance (C#)Shows how to enable implicit conversion of generic type parameters in interfaces and delegates.
Expression Trees (C#)Explains how you can use expression trees to enable dynamic modification of executable code.
Iterators (C#)Describes iterators, which are used to step through collections and return elements one at a time.
Language-Integrated Query (LINQ) (C#)Discusses the powerful query capabilities in the language syntax of C#, and the model for querying relational databases, XML documents, datasets, and in-memory collections.
Object-Oriented Programming (C#)Describes common object-oriented concepts, including encapsulation, inheritance, and polymorphism.
Reflection (C#)Explains how to use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties.
Serialization (C# )Describes key concepts in binary, XML, and SOAP serialization.
Threading (C#)Provides an overview of the .NET threading model and shows how to write code that performs multiple tasks at the same time to improve the performance and responsiveness of your applications.

LINQ - Query Operators

A set of extension methods forming a query pattern is known as LINQ Standard Query Operators. As building blocks of LINQ query expressions, these operators offer a range of query capabilities like filtering, sorting, projection, aggregation, etc.
LINQ standard query operators can be categorized into the following ones on the basis of their functionality.
  • Filtering Operators
  • Join Operators
  • Projection Operations
  • Sorting Operators
  • Grouping Operators
  • Conversions
  • Concatenation
  • Aggregation
  • Quantifier Operations
  • Partition Operations
  • Generation Operations
  • Set Operations
  • Equality
  • Element Operators

Filtering Operators

Filtering is an operation to restrict the result set such that it has only selected elements satisfying a particular condition.
OperatorDescriptionC# Query Expression SyntaxVB Query Expression Syntax
whereFilter values based on a predicate functionwhereWhere
OfTypeFilter values based on their ability to be as a specified typeNot ApplicableNot Applicable

Join Operators

Joining refers to an operation in which data sources with difficult to follow relationships with each other in a direct way are targeted.
OperatorDescriptionC# Query Expression SyntaxVB Query Expression Syntax
JoinThe operator join two sequences on basis of matching keysjoin … in … on … equals …From x In …, y In … Where x.a = y.a
GroupJoinJoin two sequences and group the matching elementsjoin … in … on … equals … into …Group Join … In … On …

Projection Operations

Projection is an operation in which an object is transformed into an altogether new form with only specific properties.
OperatorDescriptionC# Query Expression SyntaxVB Query Expression Syntax
SelectThe operator projects values on basis of a transform functionselectSelect
SelectManyThe operator project the sequences of values which are based on a transform function as well as flattens them into a single sequenceUse multiple from clausesUse multiple From clauses

Sorting Operators

A sorting operation allows ordering the elements of a sequence on basis of a single or more attributes.
OperatorDescriptionC# Query Expression SyntaxVB Query Expression Syntax
OrderByThe operator sort values in an ascending orderorderbyOrder By
OrderByDescendingThe operator sort values in a descending orderorderby ... descendingOrder By ... Descending
ThenByExecutes a secondary sorting in an ascending orderorderby …, …Order By …, …
ThenByDescendingExecutes a secondary sorting in a descending orderorderby …, … descendingOrder By …, … Descending
ReversePerforms a reversal of the order of the elements in a collectionNot ApplicableNot Applicable

Grouping Operators

The operators put data into some groups based on a common shared attribute.
OperatorDescriptionC# Query Expression SyntaxVB Query Expression Syntax
GroupByOrganize a sequence of items in groups and return them as an IEnumerable collection of type IGroupinggroup … by -or- group … by … into …Group … By … Into …
ToLookupExecute a grouping operation in which a sequence of key pairs are returnedNot ApplicableNot Applicable

Conversions

The operators change the type of input objects and are used in a diverse range of applications.
OperatorDescriptionC# Query Expression SyntaxVB Query Expression Syntax
AsEnumerableReturns the input typed as IEnumerableNot ApplicableNot Applicable
AsQueryableA (generic) IEnumerable is converted to a (generic) IQueryableNot ApplicableNot Applicable
CastPerforms casting of elements of a collection to a specified typeUse an explicitly typed range variable. Eg:from string str in wordsFrom … As …
OfTypeFilters values on basis of their , depending on their capability to be cast to a particular typeNot ApplicableNot Applicable
ToArrayForces query execution and does conversion of a collection to an arrayNot ApplicableNot Applicable
ToDictionaryOn basis of a key selector function set elements into a Dictionary and forces execution of a LINQ queryNot ApplicableNot Applicable
ToListForces execution of a query by converting a collection to a ListNot ApplicableNot Applicable
ToLookupForces execution of a query and put elements into a Lookup on basis of a key selector functionNot ApplicableNot Applicable

Concatenation

Performs concatenation of two sequences and is quite similar to the Union operator in terms of its operation except of the fact that this does not remove duplicates.
OperatorDescriptionC# Query Expression SyntaxVB Query Expression Syntax
ConcatTwo sequences are concatenated for the formation of a single one sequence.Not ApplicableNot Applicable

Aggregation

Performs any type of desired aggregation and allows creating custom aggregations in LINQ.
OperatorDescriptionC# Query Expression SyntaxVB Query Expression Syntax
AggregateOperates on the values of a collection to perform custom aggregation operationNot ApplicableNot Applicable
AverageAverage value of a collection of values is calculatedNot ApplicableAggregate … In … Into Average()
CountCounts the elements satisfying a predicate function within collectionNot ApplicableAggregate … In … Into Count()
LonCountCounts the elements satisfying a predicate function within a huge collectionNot ApplicableAggregate … In … Into LongCount()
MaxFind out the maximum value within a collectionNot ApplicableAggregate … In … Into Max()
MinFind out the minimum value existing within a collectionNot ApplicableAggregate … In … Into Min()
SumFind out the sum of a values within a collectionNot ApplicableAggregate … In … Into Sum()

Quantifier Operations

These operators return a Boolean value i.e. True or False when some or all elements within a sequence satisfy a specific condition.
OperatorDescriptionC# Query Expression SyntaxVB Query Expression Syntax
AllReturns a value ‘True’ if all elements of a sequence satisfy a predicate conditionNot ApplicableAggregate … In … Into All(…)
AnyDetermines by searching a sequence that whether any element of the same satisfy a specified conditionNot ApplicableAggregate … In … Into Any()
ContainsReturns a ‘True’ value if finds that a specific element is there in a sequence if the sequence doe not contains that specific element , ‘false’ value is returnedNot ApplicableNot Applicable

Partition Operators

Divide an input sequence into two separate sections without rearranging the elements of the sequence and then returning one of them.
OperatorDescriptionC# Query Expression SyntaxVB Query Expression Syntax
SkipSkips some specified number of elements within a sequence and returns the remaining onesNot ApplicableSkip
SkipWhileSame as that of Skip with the only exception that number of elements to skip are specified by a Boolean conditionNot ApplicableSkip While
TakeTake a specified number of elements from a sequence and skip the remaining onesNot ApplicableTake
TakeWhileSame as that of Take except the fact that number of elements to take are specified by a Boolean conditionNot ApplicableTake While

Generation Operations

A new sequence of values is created by generational operators.
OperatorDescriptionC# Query Expression SyntaxVB Query Expression Syntax
DefaultIfEmptyWhen applied to an empty sequence, generate a default element within a sequenceNot ApplicableNot Applicable
EmptyReturns an empty sequence of values and is the most simplest generational operatorNot ApplicableNot Applicable
RangeGenerates a collection having a sequence of integers or numbersNot ApplicableNot Applicable
RepeatGenerates a sequence containing repeated values of a specific lengthNot ApplicableNot Applicable

Set Operations

There are four operators for the set operations, each yielding a result based on different criteria.
OperatorDescriptionC# Query Expression SyntaxVB Query Expression Syntax
DistinctResults a list of unique values from a collection by filtering duplicate data if anyNot ApplicableDistinct
ExceptCompares the values of two collections and return the ones from one collection who are not in the other collectionNot ApplicableNot Applicable
IntersectReturns the set of values found t be identical in two separate collectionsNot ApplicableNot Applicable
UnionCombines content of two different collections into a single list that too without any duplicate contentNot ApplicableNot Applicable

Equality

Compares two sentences (enumerable ) and determine are they an exact match or not.
OperatorDescriptionC# Query Expression SyntaxVB Query Expression Syntax
SequenceEqualResults a Boolean value if two sequences are found to be identical to each otherNot ApplicableNot Applicable

Element Operators

Except the DefaultIfEmpty, all the rest eight standard query element operators return a single element from a collection.
OperatorDescriptionC# Query Expression SyntaxVB Query Expression Syntax
ElementAtReturns an element present within a specific index in a collectionNot ApplicableNot Applicable
ElementAtOrDefaultSame as ElementAt except of the fact that it also returns a default value in case the specific index is out of rangeNot ApplicableNot Applicable
FirstRetrieves the first element within a collection or the first element satisfying a specific conditionNot ApplicableNot Applicable
FirstOrDefaultSame as First except the fact that it also returns a default value in case there is no existence of such elementsNot ApplicableNot Applicable
LastRetrieves the last element present in a collection or the last element satisfying a specific conditionNot ApplicableNot Applicable
LastOrDefaultSame as Last except the fact that it also returns a default value in case there is no existence of any such elementNot ApplicableNot Applicable
SingleReturns the lone element of a collection or the lone element that satisfy a certain conditionNot ApplicableNot Applicable
SingleOrDefaultSame as Single except that it also returns a default value if there is no existence of any such lone elementNot ApplicableNot Applicable
DefaultIfEmptyReturns a default value if the collection or list is empty or nullNot ApplicableNot Applicable