Страницы

Поиск по вопросам

понедельник, 24 июня 2019 г.

Binding к this[enum] свойству экземпляра класса

Есть enum
namespace namespace1.namespace2{ enum PropertyObject { A=1, B=2, ... } }
и класс совершенно в другом namespace
public class MyClass { public Object this[namespace1.namespace2.PropertyObject property] { get { return ...; } } }
Список экземпляров всунут в ItemsSource ListView, есть также DataTemplate забитый как ItemTemplate у ListView

я уверен, что данный PropertyObject у экземпяров установлен, однако пишет, что не может достучаться до этого свойства, как создать валидный Binding к этим свойствам?
ошибка: System.Windows.Data Error: 40 : BindingExpression path error: '[]' property not found on 'object' ''MyClass' (HashCode=55693485)'. BindingExpression:Path=this[namespace1.namespace2.PropertyObject.A]; DataItem='MyClass' (HashCode=55693485); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')


Ответ

Вы используете неверный синтаксис для получения значения перечисления. В рамках XAML пространства имён в сборках (namespace в C#) и пространства имён в XML (xmlns в XML) задаются в шапке файла. При этом даже указание точного типа может не понадобиться: XAML достаточно умный, чтобы приобразовать строку к перечислению самостоятельно.
Понятия "this" в биндингах тоже нет. Скорее всего, вам нужен или текущий контекст (Path='.' или просто Path=''), или текущий элемент (RelativeSource='{RelativeSource Self}' и прочие).
Положим, у нас есть следующий код:
namespace HakunaMatata { public partial class MainWindow { public MainWindow () { InitializeComponent(); DataContext = new Model(); } }
public class Model { public string this [Other.Property prop] => prop.ToString() + " from Indexer"; } }
namespace Other { public enum Property { Foo, Bar, } }
Тогда все из способов обращения к индексатору будут работать корректно:

Возможно ли в Hibernate при связывании таблиц (@OneToMany @ManyToOne) получить вместо объекта только поле Id?

Суть проблемы в том что у меня Класс связанный в древовидную структуру по принципу предок/потомки, но когда я получаю объект у которого есть предок и потомки из БД вытягиваются не только эти объекты, но и объекты связанные с предком и потомками, а мне достаточно было бы получать только Id предка и списки List Id потомков, возможно ли связывать таблицы и получать только их Id, не вытягивая из БД весь остальной фарш?
сейчас так:
@Entity @Table(name="testpage") public class TestPage { @Id @Column(name="id") @GeneratedValue(strategy=GenerationType.AUTO) private long Id; @Column(unique=true,nullable=false) private String Name; private int position; @ManyToOne(fetch = FetchType.EAGER) @JoinColumn() @JoinTable(name="parent_testpage",joinColumns=@JoinColumn(name="page_id", referencedColumnName="id"), inverseJoinColumns=@JoinColumn(name="parent_id", referencedColumnName="id")) private TestPage Parent; @OneToMany(fetch = FetchType.EAGER) @JoinTable(name="parent_testpage",joinColumns=@JoinColumn(name="parent_id", referencedColumnName="id"), inverseJoinColumns=@JoinColumn(name="page_id", referencedColumnName="id")) private List Child;
...getters and setters }
хотелось бы так:
@Entity @Table(name="testpage") public class TestPage { @Id @Column(name="id") @GeneratedValue(strategy=GenerationType.AUTO) private long Id; @Column(unique=true,nullable=false) private String Name; private int position; @ManyToOne(fetch = FetchType.EAGER) @JoinColumn() @JoinTable(name="parent_testpage",joinColumns=@JoinColumn(name="page_id", referencedColumnName="id"), inverseJoinColumns=@JoinColumn(name="parent_id", referencedColumnName="id")) private long ParentId;
@OneToMany(fetch = FetchType.EAGER) @JoinTable(name="parent_testpage",joinColumns=@JoinColumn(name="parent_id", referencedColumnName="id"), inverseJoinColumns=@JoinColumn(name="page_id", referencedColumnName="id")) private List ChildIds;
...getters and setters
}


Ответ

Сразу оговорюсь, что это касается JPA. У Hibernate есть ещё какие-то свои родные механизмы - я их не знаю.
Только отдельный запрос, как говорит Ruslan Nekura, поможет получить id child-ов. (Но есть ещё один вариант. О нём чуть ниже)
Не работает JPA по-другому. Не ссылается он на отдельные поля других entity. Только на объект целиком. parent_Id - это поле в того же самого entity. Оно может быть использовано и так и сяк и даже одновременно:
... @JoinTable(name="parent_testpage", joinColumns=@JoinColumn(name="page_id", referencedColumnName="id"), inverseJoinColumns=@JoinColumn(name="parent_id", referencedColumnName="id")) private TestPage Parent;
@Column(name="parent_id", insertable=false, updatable=false) private Long parentId; ...
Если используются одновременно, то одно отображение обязательно отметить как "только для чтения". В примере это parentId с параметрами аннотации insertable, updatable = false.
Со списком child-ов, как уже сказано выше, такой номер не пройдёт.
И вот ещё одна метода. Можно сделать view в базе с полями parent_id и child_id.
CREATE VIEW view_child_ids (long parent_id, long child_id) AS SELECT parent_id, id FROM testpage WHERE parent_id IS NOT NULL;
Отобразить эту view в виде Basic ElementCollection:
... @ElementCollection @CollectionTable(name = "view_child_ids", joinColumns=@JoinColumn(name = "parent_id")) @Column(name = "child_id") private List childIds; ...
Для этой view ещё надо будет всяких правил/триггеров определить на случай каскадных удаления/изменения. Есть в этом свои недостатки, но не буду их упоминать. Они проявляются при определённых обстоятельствах. Может Вам повезёт, ведь никто не знает всей Вашей задумки. Сам предпочитаю запросы.
Радикальный вариант - уйти с JPA/Hibernate на альтернативный способ доступа к данным, работающий на других принципах. Active-record какой-нибудь.

Как в PHPMyAdmin посмотреть триггеры в MySQL?

Как в PHPMyAdmin посмотреть триггеры в MySQL? Не могу найти этот раздел, есть раздел процедуры, но там написано "у вас нет прав для создания процедур" . Я свой триггер загрузил через SQL консоль в PHPMyAdmin, и он работает, но как его найти не знаю.


Ответ

Заходите в БД и в верхней панели наводите курсор на "Ещё":