Search This Blog

Wednesday, December 30, 2015

EF - Use of complex types that are not registered in DbContext and have no key property

I want to highlight a minor usability improvement built into v15.2 for our Entity Framework fans. This is all about a simpler integration of complex types without keys (learn more from EF docs...). 

The situation is already pretty much summarized in the Support Center, and here I just want to re-post the main details. To begin with, consider the following EF classes:

[C#]
public class Product { public Product() { PriceRange = new Range(); } public Int32 ID { get; set; } public String Name { get; set; } public Range PriceRange { get; set; } } public class Range { public Range() { } public Decimal Low { get; set; } public Decimal High { get; set; } }
public class EFDemoDbContext : DbContext {
    ...
    public DbSet<Product> Products { get; set; }
    ...
}

Note that the Range class has no key property and Entity Framework does not map this class to a separate database table. By default, properties of such a class persist in the table mapped to the parent Product class, where the Range type property is declared. So, the Product table will have the ID, NamePriceRange_Low and PriceRange_High columns:

Wednesday, December 23, 2015

The GetObjectsNonReenterant error for security permissions with complex criteria - Fixed in v15.2.5

In v15.2.5 we have made improvements at both the XPO and XAF levels to avoid the Entering state 'GetObjectsNonReenterant' from state 'CommitTransactionNonReenterant, CommitChangesToDataLayer' is prohibited due to state 'CommitChangesToDataLayer' error that might occur while evaluating security permission criteria involving collections during the object saving procedure (S170995). Our previous attempt was unsuccessful and I apologize for this and all the inconvenience this has caused you and your business.

Our new low-level solution does not require extra options on your side, and I invite you to test a new 15.2 build containing these improvements: 


I am looking forward to hearing from you on how these improvements work in your real projects after installing this build and running the Project Converter tool. Thanks in advance!


Tuesday, December 22, 2015

MediaDataObject - Declaring images as object references instead of byte array

In v15.2 we have introduced the new MediaDataObject business class. The use of this type mainly reduces traffic in Web apps because images are cached in the browser cache (compared to images declared as byte[]).  

We have invented this solution when optimizing the new Web style performance on mobile devices. 
For instance, in our XCRM demo application (installed to C:\Users\Public\Documents\DevExpress Demos 15.2\Components\eXpressApp Framework\XCRM\, by default) the avatar picture in the top right corner is implemented using MediaDataObject:



Both WinForms and ASP.NET Image Property Editors are used automatically for properties of the MediaDataObject type, the delayed loading is also always enabled - no special attributes are required for this. However, you still can apply the ImageEditorAttribute to customize the editor's options. 

XPO and EntityFramework versions of this type are available in the Business Class LibraryRefer to the eXpressApp Framework > Concepts > Business Model Design > Data Types Supported by built-in Editors > BLOB Image Properties article to see example property declarations for your favorite ORM.

Monday, December 21, 2015

JFYI - New RefreshXXX methods allowing to reload the underlying data source of a View or ViewItem

Just wanted to make sure you are aware of this small usability improvement, which will help you accomplish daily development tasks easier and in more intuitively.

From https://www.devexpress.com/Support/Center/Question/Details/S170756 (done in v15.2.4):

The following methods are added to the View and ViewItem classes:[C#]
public virtual void RefreshDataSource()
public void Refresh(bool refreshDataSource)
Internally, the Refresh method calls RefreshDataSource when the refreshDataSource parameter is set to true.

The RefreshDataSource method overloads are:
ListView.RefreshDataSource -  calls the CollectionSourceBase.Reload method;
DetailView.RefreshDataSource  - calls the IObjectSpace.ReloadObject method and passes the DetailView.CurrentObject object to it;
ListPropertyEditor.RefreshDataSource - calls the ListView.RefreshDataSource method;
DetailPropertyEditor.RefreshDataSource - calls the DetailView.RefreshDataSource method.

Avoid auto-saving a master when a new non-aggregated child is created and making the New Action available for many-to-many lists

In v15.2.4 we have added the LinkNewObjectToParentImmediately property to the XafApplication and NewObjectViewController classes. 

By default, XafApplication.LinkNewObjectToParentImmediately is set to true to keep the behavior of existing applications unchanged (a new object linked to the master object is created and the master object is committed when the New action is executed in the nested List View). However, in new applications created in the 15.2 version, the default value is overridden to false in code generated by the Solution Wizard.

Use XafApplication.LinkNewObjectToParentImmediately to change the behavior globally (note that this property is hidden in the Application Designer and you can set it only in code). Use NewObjectViewController.LinkNewObjectToParentImmediately to change the behavior for a specific View. The behavior of aggregated collections is not changed.

There are several positive results from this LinkNewObjectToParentImmediately = false change:
1. A reference to the master object is visible in the new child object immediately. 
2. The master object is not committed and the link is not created when the New action is executed in the nested List View. At the database level that means that the reference to the master table is not added to the new child record immediately. The link is created later when the child object is committed. To keep the link, a user should save the master object; otherwise, the unlinked child object will be saved.
3. The New Action is now available directly in the nested ListView or the Link dialog for many-to-many XPO associations!

There were a lot of customer requests for the last two things, so I hope you will like this news. Please let me know what you think in comments.



Monday, December 14, 2015

DashboardView - Allowing end-users to delete created dashboards via the application UI

In v15.2.4 we have added the DeleteDashboardsController which provides the DeleteDashboard Action. This Action is located in the Tools category and invokes a popup dialog with a list of all dashboard views defined in the user's model differences.

In this popup you can select one or more dashboards and click Delete to remove them. The DeleteDashboardsController.CanDeleteParentGroup property specifies whether or not the dashboard's parent group is deleted when you remove the last dashboard in this group. 

The DeleteDashboard Action is active when there are dashboards that can be deleted and the EnableCreation property of the Options | Dashboards node is set to true in the Application Model.


Previously, it was only possible to manage these user-defined dashboards via the Model Editor or in code. So, I hope you will now be able to enable this feature for your clients without the fear of being overloaded with support calls about removing unwanted stuff.

You can find more information on this XAF feature in the online docs here:

XPO ORM Data Model Designer and Wizard FAQ

My fellow colleague Michael has recently written an article based on the most popular support calls regarding the visual designer that XPO ships with, for editing visual data models. Some things may already be known to you, but others are worth repeating and I hope you will find this short doc helpful:



How to hide or filter out certain types from the drop-down editor for the System.Type properties

I want to share my recent article on the subject that demonstrates yet another example of how flexible and powerful XAF really is. There, I will describe three possible ways of accomplishing the same task, starting with the most recommended platform-agnostic solution at the business model level (write once, work everywhere) and finishing by manipulating end control properties in the UI for certain platforms and contexts. 


So, let me quite myself from this KB article in our Support Center:

Tuesday, October 27, 2015

Conditional Formatting for WinForms Tree List Editor

This is merely a follow up to my previous post:
How to enable the Conditional Formatting feature of the WinForms GridControl in the XAF GridListEditor and preserve ListView formatting settings between runs?

I want to share a similar solution for the TreeListEditor, which I coded and updated according to great customer feedback recently. You can learn more on this feature from the WinForms Controls > Controls and Libraries > Tree List > Conditional Formatting and TreeListOptionsMenu.ShowConditionalFormattingItem documentation.

Here are the steps needed to use the TreeListEditor in your XAF project:
1. In the Module Designer invoked for YourSolutionName.Module.Win/Module.xx file, add the Tree List Editor module to allow Visual Studio to automatically add required assembly references;
2. Copy and include this C# source file into YourSolutionName.Module.Win project (vb.net guys can either use this approach OR convert this code into their language using free tools).

Please track the corresponding Support Center thread to be automatically notified of any changes or other improvements in this regard.

As always, I am looking forward to hearing from you on whether you find this feature helpful for your apps.


Thursday, October 22, 2015

Avoiding the GetObjectsNonReenterant error for security permissions with complex criteria

UPDATE2

UPDATE1
During further testing we found that the new solution is not appropriate for certain scenarios (e.g., when new objects are created and saved under certain scenarios) and eventually decided not to make this new mode as default in v15.2. We will also mark the CanCheckModifiedObject option as obsolete for now. We will try to approach this problem from another angle at a lower XPO level. As always, we will keep you posted of our results once have anything to share. We apologize for all the inconvenience here.



OUTDATED
Let me quote myself from the Security - Avoid the GetObjectsNonReenterant error while evaluating security permission criteria involving collections during the object saving procedure thread in our Support Center:

We have provided the new CanCheckModifiedObject property in the DevExpress.ExpressApp.Security.SecurityRule class, which can be used to avoid loading additional collections and thus throwing the "GetObjectsNonReenterant" error from XPO internals while evaluating security permission criteria during the object saving procedure.


If CanCheckModifiedObject = True, both currently modified and existing database records are validated by security rules (the current behavior leading to the error).

Otherwise, if CanCheckModifiedObject = False, only the existing database records are validated by security rules. The latter configuration should be suitable in most business scenarios we are aware of and this will be the default configuration in v15.2.

Thus, to avoid the "Entering state 'GetObjectsNonReenterant' from state 'CommitTransactionNonReenterant, CommitChangesToDataLayer' is prohibited due to state 'CommitChangesToDataLayer' for 'DevExpress.Xpo.UnitOfWork(35)'" error in v15.1.8+
set the static DevExpress.ExpressApp.Security.SecurityRule.CanCheckModifiedObject property to False in the entry point of your application; e.g., within the constructor of your platform-agnostic module (YourSolutionName.Module/Module.xx) OR within the Main method of the WinForms app (YourSolutionName.Win/Program.xx) OR within the Application_Start method of the ASP.NET app (YourSolutionName.Web/Global.xx).

For instance, below is the code I added in the MainDemo.Module/Module.cs file of the project from the E4045: 
How to separate data between employees and managers of different departments using security permissions example while testing this improvement locally:

Friday, October 9, 2015

Improving performance when a large portion of data matches a workflow activity criterion

Here is a real customer scenario from a related Support Center thread

"Hi, I have an application with several workflows that work ok in my local computer (testing with few records), but when I deploy the workflows to a server and the workflow gets approximately 1,500,000 records that match the criteria the workflow service crashes...
I've done some testing and this only happens when the workflow needs to deal with a lot of data, workflows that deal with less records don't have a problem. I've been looking for an alternative like XPCursor or something similar to ask the workflow to page the records that meet the criteria but I haven't found any."


After some time, we could replicate this behavior locally and found that it could be easily improved upon on our side. In short, our solution is in using XafDataView + a sort of paging  when first querying and processing records that match a certain workflow activity definition criteria in the workflow service. 

A minor improvement to the Object Property Editors that represent aggregated object references in the UI


Starting with version 15.1.8, you can easily specify a custom DetailView for ObjectPropertyEditor via the Model Editor at the DetailView | Items or ListView | Columns node levels in the Application Model:


Thus,  the IModelMemberViewItem.View  attribute now helps you specify custom Views for all object reference property editors used in both ListView and DetailView.

Previously, this task required a custom-tailored code solution like in the How to change ASPxObjectPropertyEditor's DetailView thread.  So, I hope you find this addition helpful.

Tuesday, October 6, 2015

Confirm unsaved changes to avoid losing data when navigating to another web page - YOUR FEEDBACK IS NEEDED

Scenario

Imagine you are in an XAF ASP.NET app context and just edited a record in the DetailView or ListView directly (e.g., linked or unlinked related details, typed something in the text box, changed drop downs, etc.) and then accidentally clicked a navigation item or some other link within the app...If the Save Action was not explicitly executed before that accidental action took place, there is a risk of losing your recent edits...and sadly this sometimes happens. Thankfully, this is not the case for the WinForms platform, where it is already handled.

Current solutions

There are some custom-tailored solutions available in the Support Center (onetwo), but they far from being ideal, to be honest.

Good news

As part of our continuous effort to improve the XAF Web UI (be sure to check it), the new v15.2 (should be out around December, as always) will contain a built-in solution for the aforementioned problem. 

More good news

Friday, October 2, 2015

Avoiding repetitive customizations for Views of the same type or subclasses via the Model Editor - YOUR FEEDBACK IS NEEDED

Prerequisites

Imagine you have the following data model classes:

class Party {...}

class Person : Party {...}
class Organization: Party {...}



XAF automatically generated several default root and nested Views for them in the Application Model. You can also create custom Views via the Model Editor on your own. For instance, you might end up with the following list under the Views node:


    Party_ListView
    Person_ListView1
    Person_ListViewN
    Organization_ListView1
    Organization_ListViewN



Scenario


Imagine your first goal is to customize the appearance of the ListView for the base class - Party_ListView according to your client needs.To accomplish this, you locate the Party_ListView node in the Model Editor and make various customizations to its columns. In particular, 1. edit captions for the Photo, Address1, Address2 columns; moved the Photo column after the Address1 and Address2 ones; 2. made changes to the ListView node properties such as set IsGroupPanelVisible, AllowEdit and other options in the property grid.


What if your second goal is to have a similar appearance for other ListViews where Party records are shown, e.g., Person_ListView, Organization_ListView1, Party_LookupListView or even Company_Persons_ListView (see the poll questions in the end)?


Thursday, September 17, 2015

How to enable the Conditional Formatting feature of the WinForms GridControl in the XAF GridListEditor and preserve ListView formatting settings between runs?

In short, this feature allows your end-user to sort or group the data inside the grid AND to visualize selected cells, rows with data bars, icons and predefined or custom appearance schemes. Refer to the following XtraGrid documentation for more information on this feature: 



In general, accomplishing this task in an XAF app consists of several independent parts:
2. Integrating this solution in the GridListEditor using a ViewController  as described in the Access Grid Control Properties  help topic.
3. Serializing the grid's formatting rules information, taking into account the fact that it uses a different mechanism for storing settings, which is based on the Application Model. In XAF, it is best to extend the ListView node with a string property that will hold a serialization representation of formatting rules. Refer to the How to: Extend the Application Model  article for more details.