Каскадные представления списка поиска DevExpress XAF

Я создал приложение DevExpress XAF Blazor.
У меня есть четыре таблицы (страницы)
Первая из них Категория связана отношением "один ко многим" с AssignedContractorCategory table
-oid string
-Title string

private string _Title;
public string Title
{
    get { return _Title; }
    set { SetPropertyValue(nameof(Title), ref _Title, value); }
}

[DevExpress.Xpo.Association("Category-AssignedContractorCategory")]
public XPCollection<AssignedContractorCategory> AssignedContractorCategory
{
    get
    {
        return GetCollection<AssignedContractorCategory>(nameof(AssignedContractorCategory));
    }
}

Второй — Contractor, связанный отношением «один ко многим» с AssignedContractorCategory table
-oid string
-Title string

private string _Title;
public string Title
{
    get { return _Title; }
    set { SetPropertyValue(nameof(Title), ref _Title, value); }
}

[DevExpress.Xpo.Association("Contractor-AssignedContractorCategory")]
public XPCollection<AssignedContractorCategory> AssignedContractorCategory
{
    get
    {
        return GetCollection<AssignedContractorCategory>(nameof(AssignedContractorCategory));
    }
}

Третий — AssignedContractorCategory, связанный отношением «один ко многим» с Bill table
-oid string
-FKCategory string
-FKContractor нить

private Category _Category;
[Association("Category-AssignedContractorCategory")]
public Category Category
{
    get { return _Category; }
    set { SetPropertyValue(nameof(Category), ref _Category, value); }
}

private Contractor _Contractor;
[Association("Contractor-AssignedContractorCategory")]
public Contractor Contractor
{
    get { return _Contractor; }
    set { SetPropertyValue(nameof(Contractor), ref _Contractor, value); }
}

Четвертый — Bill
-oid string
-FKAssignedContractorCategory string
-Amount double

private Category _Category;
public Category Category
{
    get { return _Category; }
    set { SetPropertyValue(nameof(Category), ref _Category, value); }
}

private Contractor _Contractor;
public Contractor Contractor
{
    get { return _Contractor; }
    set { SetPropertyValue(nameof(Contractor), ref _Contractor, value); }
}

private double _Amount;
public double Amount
{
    get { return _Amount; }
    set { SetPropertyValue(nameof(Amount), ref _Amount, value); }
}

На странице счета я хочу показать:
Категория (представления списка поиска), и после того, как я выбрал одну категорию, она показывает только Подрядчика (представления списка поиска), которые связаны с таблицей AssignedContractorCategory
Обратите внимание, что я новичок.


person M.Bouabdallah    schedule 17.03.2021    source источник


Ответы (1)


Шаг 1. В классе Bill украсьте свойство Category атрибутом ImmediatePostData. Это гарантирует, что сеттер будет вызываться сразу после каждого изменения пользовательского интерфейса:

[ImmediatePostData]
public Category Category

Шаг 2. В классе Bill добавьте атрибут DataSourceProperty к свойству Contractor, а затем реализуйте соответствующее свойство, которое всегда возвращает правильный выбор подрядчиков. Обратите внимание, что я украшаю новое свойство ContractorSelection [Browsable(false)], чтобы оно было полностью невидимым в пользовательском интерфейсе XAF:

private Contractor _Contractor;
[DataSourceProperty(nameof(ContractorSelection))]
public Contractor Contractor
{
    get { return _Contractor; }
    set { SetPropertyValue(nameof(Contractor), ref _Contractor, value); }
}

[Browsable(false)]
public IList<Contractor> ContractorSelection
{
    get
    {
       return Category?.AssignedContractorCategory.Select(i => i.Contractor).Distinct().ToList();
    }
}

Шаг 3: проблема заключается в том, что XAF не обновляет автоматически свой внутренний кэш коллекции ContractorSelection при изменении файла Category. Чтобы это работало, вам нужно изменить установщик вашего свойства Category и сообщить XAF, что свойство Contractor также изменилось:

[ImmediatePostData]
public Category Category
{
    get { return _Category; }
    set 
    { 
        SetPropertyValue(nameof(Category), ref _Category, value);
        if (!IsLoading)
        {
            OnChanged(nameof(Contractor));
        }
    }
}

Я протестировал это, и оно отлично работает в XAF Blazor.


Альтернативный метод:

Если вы предпочитаете, чтобы ваши объекты фильтровались БД (идеально, если у вас большая коллекция подрядчиков), вы можете вместо этого использовать атрибут DataSourceCriteria, а затем удалить свойство ContractorSelection из моего исходного решения. Весь остальной код остается прежним:

private Contractor _Contractor;
[DataSourceCriteria("AssignedContractorCategory[Category = '@This.Category'].Count > 0")]
public Contractor Contractor
{
    get { return _Contractor; }
    set { SetPropertyValue(nameof(Contractor), ref _Contractor, value); }
}

Дополнительная информация:

  • Мы не определили, что должен отображать XAF, когда не выбрана ни одна категория. Ознакомьтесь с документацией XAF по атрибуту DataSourceProperty, чтобы узнать, как указать соответствующее поведение в случае, если источник данных имеет значение null.
  • Вы также можете использовать установщик Category для принудительного применения других ограничений, таких как установка Contractor на ноль, если текущий выбранный Contractor не является частью выбранной категории. Чем больше у вас взаимозависимых свойств, тем сложнее это становится.
  • Если ваш класс AssignedContractorCategory используется только как чистая связь между Contractor и Category (без дополнительных свойств), вы можете рассмотреть возможность использования встроенного в XPO ассоциации "многие ко многим"
person Marco    schedule 22.03.2021
comment
Я действительно очень благодарен вам за помощь - person M.Bouabdallah; 24.03.2021