属性表达式无效。表达式应代表属性

时间:2013-11-23 23:48:58

标签: entity-framework-6

我有这两个实体

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; }
    }

PathIPathHavingEntity界面中定义。

在我的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 's => 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 }'.

有什么问题?

5 个答案:

答案 0 :(得分:26)

在我的情况下,我在Model Classes上做的唯一修改忘了将{get; set;}放在属性声明中,因此...它解决了我的问题。

像这样:

在:

 public int Supplier_ID;
 public String Supplier_Code;

后:

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

请检查您的模型类应具有Get/Set属性

答案 1 :(得分:4)

今天几个小时我一直在努力解决类似的问题,终于能够解决它了。我不确定这是否适用于您的情况,但值得研究。

问题可能是由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 :(得分:2)

EF不会为没有getter或setter的属性创建列。例如,EF不会为以下“城市和年龄”属性创建列。

using System.ComponentModel.DataAnnotations;

public class Student
{
    private int _age = 0;

    public int StudentId { get; set; }
    public string StudentName { get; set; }
    public string City { get{ return StudentName;}  }
    public int Age { set{ _age = value;}  }
}

引用:https://www.entityframeworktutorial.net/code-first/notmapped-dataannotations-attribute-in-code-first.aspx

答案 3 :(得分:0)

就我而言,更改mapper中的以下值有效。

自:

.tox/py34/lib/python3.4/copy.py:155: in deepcopy
y = copier(x, memo)
.tox/py34/lib/python3.4/copy.py:246: in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
.tox/py34/lib/python3.4/copy.py:182: in deepcopy
    y = _reconstruct(x, rv, 1, memo)
.tox/py34/lib/python3.4/copy.py:300: in _reconstruct
    state = deepcopy(state, memo)
.tox/py34/lib/python3.4/copy.py:155: in deepcopy
    y = copier(x, memo)
.tox/py34/lib/python3.4/copy.py:246: in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
.tox/py34/lib/python3.4/copy.py:182: in deepcopy
    y = _reconstruct(x, rv, 1, memo)
.tox/py34/lib/python3.4/copy.py:301: in _reconstruct
    if hasattr(y, '__setstate__'):
.tox/py34/lib/python3.4/site-packages/zope/i18n/locales/inheritance.py:116: in __getattr__
    selfUp = self.getInheritedSelf()
.tox/py34/lib/python3.4/site-packages/zope/i18n/locales/__init__.py:670: in getInheritedSelf
    language = self.id.language
.tox/py34/lib/python3.4/site-packages/zope/i18n/locales/inheritance.py:116: in __getattr__
    selfUp = self.getInheritedSelf()
.tox/py34/lib/python3.4/site-packages/zope/i18n/locales/__init__.py:670: in getInheritedSelf
    language = self.id.language
!!! Recursion detected (same locals & position)

要:

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

答案 4 :(得分:0)

在任何其他答案中都没有提到的是,在任何情况下,问题的根源都是相同的:作为AddOrUpdate方法的参数传入的“自定义标识表达式”必须是插入或更新的实体的有效属性。另外,它在那里将不接受ComplextType.Property。

例如:

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

请注意,使用AlbumPath时此问题已解决,并且还请注意,匿名类型不需要创建其他字段。相反,您只需要指定属性名称即可。

值得一提的是,在将AddOrUpdate用作the result can be destructive时要小心。