Необработанное исключение при использовании FirstOrDefault() с CollectionViewSource?

#wpf #entity-framework-4 #collectionviewsource

#wpf #entity-framework-4 #collectionviewsource

Вопрос:

Я привязал объекты к CollectionViewSource. Затем я делаю запрос в коде. Поскольку поле id является PK, я думаю, мне следует использовать FirstOrDefault(), чтобы ускорить выполнение моего приложения. Но он всегда выдает исключение…

XAML :

 <Window.Resources>
        <CollectionViewSource x:Key="contractlogoesViewSource" d:DesignSource="{d:DesignInstance my:contractlogo, CreateList=True}" />
    </Window.Resources>
    <Grid>
        <Grid DataContext="{StaticResource contractlogoesViewSource}" HorizontalAlignment="Left" Margin="12,12,0,0" Name="grid1" VerticalAlignment="Top">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
...
 

Код, лежащий в основе :

 private void Window_Loaded(object sender, RoutedEventArgs e)
{
    VBDAdvertisement.vbdadvertisementEntities vbdadvertisementEntities = new VBDAdvertisement.vbdadvertisementEntities();            
    System.Windows.Data.CollectionViewSource contractlogoesViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("contractlogoesViewSource")));
    contractlogoesViewSource.Source = vbdadvertisementEntities.contractlogoes.Where(q => q.id.Equals(3)).FirstOrDefault();
}
 

Он выдает необработанное исключение :

 An unhandled exception of type 'System.ArgumentException' occurred in
PresentationFramework.dll
Additional information: 'VBDAdvertisement.customer' is not a valid value for
property 'Source'.
 

Но когда я опускаю FirstOrDefault() из дерева выражений, например :

 contractlogoesViewSource.Source = vbdadvertisementEntities.contractlogoes.Where(q => q.id.Equals(3));
 

Это работает хорошо!

Так почему FirstOrDefault() вызывает ошибку?
В этом случае, должен ли я использовать FirstOrDefault(), будет ли мое приложение выполняться быстрее, если я использую FirstOrDefault() ?

ps: Я разрабатываю форму редактирования, поэтому я просто хочу, чтобы был загружен один элемент.

Ответ №1:

Причина, по которой вы получаете ошибку, заключается в том, что вы не можете назначить один элемент CollectionViewSource . Если это форма редактирования, вам, вероятно, не нужен CollectionViewSource и вы можете напрямую привязаться к элементу.

Если вы сделаете это, вы можете использовать FirstorDefault() для получения первого элемента. Но в вашем случае, поскольку вы выбираете по идентификатору, я думаю, что его лучше использовать SingleOrDefault() , поскольку он более точно показывает намерение того, что вы хотите, вот так:

 contractlogoesViewSource.Source = vbdadvertisementEntities.contractlogoes.SingleOrDefault(q => q.id.Equals(3));
 

SingleOrDefault() выдаст исключение, если предикату соответствует более одного элемента, но поскольку ID является первичным ключом, это не будет проблемой для вас.

Если вы хотите использовать CollectionViewSource (но я не понимаю, почему), вы можете использовать .Take() для получения коллекции, содержащей один элемент, например:

 vbdadvertisementEntities.contractlogoes.Where(q => q.id.Equals(3)).Take(1);
 

Комментарии:

1. Привет, поле id является первичным ключом, поэтому оно также уникально. Я где-то читал, что использование FirstOrDefault() ускорит запрос, если мы уверены, что будет возвращена только 1 запись. В winform я использую FirstOrDefault() с привязкой источника без проблем, но wpf этого не делает.

2. И это форма редактирования, так что мне просто нужен один элемент для загрузки.

3. @Sun, я обновил свой ответ, чтобы сделать его более понятным для вас.