Выражение свойств недопустимо. Выражение должно представлять свойство

У меня есть эти два объекта

public class Song : IPathHavingEntity
    {
        public int Id { get; set; }
        [Required]
        public string Path { get; set; }
        [Required]
        public virtual Album Album { get; set; }
        [Required]
        public int TrackNumber { get; set; }
    }

public class Album : IPathHavingEntity
    {
        public int Id { get; set; }
        [Required]
        public string Path { get; set; }
        public virtual IEnumerable<Song> Songs { get; set; }
        [Required]
        public int AlbumNumber { get; set; }
    }

Path определяется в интерфейсе IPathHavingEntity.

В методе Seed я хочу добавить песню в таблицу Songs только в том случае, если она не существует. По этой причине я проверяю, что путь пути к альбому и комбинация пути песни не существуют уже до его добавления.

context.Songs.AddOrUpdate(
    s => new { FilePath = s.Path, AlbumPath = s.Album.Path }, 
    new Song { TrackNumber = 1, Path = "01 Intro.mp3", Album = one });

Проблема в том, что я получаю эту ошибку

The properties expression => new <>f__AnonymousType0``2(FilePath = s.Path, AlbumPath = s.Album.Path)' is not valid. The expression should represent a property: C#: 't => t.MyProperty' VB.Net: 'Function(t) t.MyProperty'. When specifying multiple properties use an anonymous type: C#: 't => new { t.MyProperty1, t.MyProperty2 }' VB.Net: 'Function(t) New With { t.MyProperty1, t.MyProperty2 }'.

В чем проблема?

Ответ 1

Я боролся с подобной проблемой в течение нескольких часов сегодня и, наконец, смог ее решить. Я не уверен, что это будет работать для вашей ситуации, но стоит исследовать.

Проблема может быть вызвана свойством Album вашего объекта Song, помеченного как virtual. Я не эксперт EF, но я не думаю, что ему нравится это свойство virtual при инициализации вашего анонимного типа. Добавьте не виртуальное свойство для пути к альбому (но сохраните свойство навигации virtual), например:

public class Song : IPathHavingEntity
{
    public int Id { get; set; }

    [Required]
    public string Path { get; set; }

    [Required]
    public virtual Album Album { get; set; }

    public string AlbumPath { get; set; }

    [Required]
    public int TrackNumber { get; set; }
}

И затем выполните AddOrUpdate, используя это не виртуальное свойство, например:

context.Songs.AddOrUpdate(
    s => new { FilePath = s.Path, AlbumPath = s.AlbumPath }, 
    new Song { TrackNumber = 1, Path = "01 Intro.mp3", Album = one });

EF должен позволять вам добавлять песни, в которых данный путь песни и путь к альбому еще не существует. Если ваш объект домена Song может иметь не виртуальное свойство AlbumPath, это другой вопрос, но это должно по крайней мере позволить вам запустить ваш метод семени в том виде, в котором вы описали.

Ответ 2

В моем случае "Единственная модификация, которую я сделал, что в классах классов забыл положить {get; set;} с объявлением свойства, таким образом... Он решил мою проблему.

Вот так:

До:

 public int Supplier_ID;
 public String Supplier_Code;

После:

 public int Supplier_ID { get; set; }
 public String Supplier_Code { get; set; }

Не забудьте проверить, что ваши классы моделей должны иметь свойство Get/Set

Ответ 3

В моем случае изменение следующих значений в маппере сработало.

От:

this.HasKey(t => new { FirstName = t.FirstName, LastName = t.LastName });

Для того, чтобы:

this.HasKey(t => new { t.FirstName, t.LastName });

Ответ 4

Ни в одном другом ответе не было упомянуто, что источник проблемы в любом показанном случае один и тот же: "выражение пользовательской идентификации", передаваемое как параметр метода AddOrUpdate, должно быть допустимое свойство объекта, который вставляется или обновляется. Кроме того, он не будет принимать ComplextType.Property там.

Например:

context.Songs.AddOrUpdate(
    s => new { k.Path, k.AlbumPath }, 
    new Song { TrackNumber = 1, Path = "01 Intro.mp3", Album = one });

Обратите внимание, что проблема была решена при использовании AlbumPath, а также обратите внимание, что анонимный тип не требует создания других полей. Вместо этого вам просто нужно указать имена свойств.

Стоит отметить, что при использовании AddOrUpdate следует соблюдать осторожность, поскольку результат может быть разрушительным.