Time flies – we are already halfway through 2020. We certainly hope that you and your loved ones are doing well and staying safe.
Here is this month’s edition of XAF Tips & Tricks. Please let us know if you find the information below of value and tell us how we can improve this content going forward. If you have a support ticket you'd like to share with the XAF developer community, feel free to post a link in the comment section below.
Interesting Support Tickets
- Core - Refresh a Detail View after saving changes in its nested List View (T900526)
- Core - When and why you need to unsubscribe from events (T893208)
- Core - We published the new NuGet package DevExpress.ExpressApp.DBUpdater (T885016)
- Blazor - Deploy an application on Ubuntu
- Security - When the Conditional Appearance Module is better than Action Permissions (T894159)
- Security - We added new validation and appearance rules for PermissionPolicyUser and PermissionPolicyRole. They help you to avoid unnecessary permission editing for administrative roles and prevent deletion of the last active Administrator or the last administrative role (T898638)
- XPO - Recommendations on asynchronous data loading (T894599)
- WinForms - Integrate a map into your XAF WinForms application (T287322)
- WinForms - Invoke the Model Editor in code and customize its default settings (for instance, focus a node) (T895223)
- WinForms - Show business objects on a Kanban Board (T886578)
- Web - Initialize a new object created in a nested List View in Batch edit mode depending on master object properties (T896906)
- Web - Indicate that a Detail View contains changes in the UI (T898453)
- Web - Download a file when clicking the OK button in a popup window
- Web - Customize a Detail View opened when clicking the New button in a lookup editor (T897024)
Resolved Issues
- Core - The SupportsAsyncLoading rule causes recurrent "IModelViewWin expected" exceptions in the Model Editor (T894836)
- XPO raises "Object reference not set" when OData is used in some circumstances (T903105)
New and Updated KB Articles
- Core - How to port an XAF platform-agnostic module from .NET Framework to .NET Standard 2.0+
- Core - FAQ: Model Editor for .NET Core and .NET Standard (CTP)
- Blazor - FAQ: XAF ASP.NET Core Blazor Server UI (CTP)
- Security - FAQ: XAF User Authentication and Group Authorization API for DevExpress XPO and Microsoft Entity Framework Core ORMs
- XPO - FAQ: Async/Await Method Support
- Troubleshooting - How to resolve the "Cannot modify Dictionary because ThreadSafeDataLayer uses it" error
- Troubleshooting - How to resolve the "Reentrancy or cross-thread operation detected" error
Documentation Updates
XPO Query Parameter Validation
We softened default parameter validation in SELECT, UPDATE, and INSERT statements and introduced a new DevExpress.Xpo.DB.QueryParameterMode enumeration. You can set the ConnectionProviderSql.QueryParameterMode field or the ConnectionProviderSql.GlobalQueryParameterMode static field as needed.
using DevExpress.Xpo.DB;
//...
ConnectionProviderSql.GlobalQueryParameterMode = QueryParameterMode.Legacy;
Unit and Functional Testing
We reworked and updated the Functional Tests (EasyTest) help section and added a new help topic to improve navigation between learning materials related to unit and functional testing.
FirstOrDefault Methods
The IObjectSpace interface includes the following new methods:
- FirstOrDefault<ObjectType>(Expression<Func<ObjectType, Boolean>>)
- FirstOrDefault<ObjectType>(Expression<Func<ObjectType, Boolean>>, Boolean)
These methods mirror our FindObject<ObjectType>(CriteriaOperator) and FindObject<ObjectType>(CriteriaOperator, Boolean) methods, but accept a lambda expression as the first parameter.
// v20.1.4:
ObjectSpace.FirstOrDefault<Person>(p => p.FirstName == "Test");
// Older versions:
ObjectSpace.FindObject<Person>(CriteriaOperator.Parse("FirstName=?", "Test"));
ObjectSpace.FindObject<Person>(new BinaryOperator(nameof(Person.FirstName), "Test"));
ObjectSpace.FindObject<Person>(new OperandProperty(nameof(Person.FirstName)) == "Test");
ObjectSpace.GetObjectsQuery<Person>().Where(p => p.FirstName == "Test").FirstOrDefault();
LINQ may be more convenient than CriteriaOperator and more natural for Entity Framework users. XPO users may also like this shortcut.
Non-Persistent Objects
- How to implement CRUD operations for Non-Persistent Objects stored remotely
- How to edit a collection of Persistent Objects linked to a Non-Persistent Object
Non-Persistent Object Enhancements
Our upcoming v20.1.5 release will offer the following enhancements to non-persistent objects.
- NonPersistentObjectSpace will include a FindObject(Type, CriteriaOperator, Boolean) method overload. This method iterates objects loaded with GetObjects, GetObject, CreateObject (etc) methods, and returns the first object that matches the specified parameters.
- NonPersistentObjectSpace supports custom fields (both calculated and non-calculated). You can create these in code and via the Model Editor (just as you would for persistent objects).
- You can inherit the new NonPersistentObjectBase class instead of creating a Non-Persistent Object item from the Template Gallery.