Dej*_*n.S 14 entity-framework code-first entity-framework-4 asp.net-mvc-2
编辑:这只发生在具有存储库的大型项目中.有没有人使用EF4和CodeFirst方法并使用存储库?请建议我.
你好.我目前正在使用EF4 CodeFirst Classes.在我的测试项目中,我有两个类,作者和书(作者得到书).我正在尝试做的是我在我的作者类中有一个AddBook,但似乎不能像我不能将它添加到集合中..这里是我的类和两个不同的例外.
public class Book
{
public virtual int BookId { get; set; }
public virtual string Title { get; set; }
public virtual Author Author { get; set; }
}
public class Author
{
public virtual int AuthorId { get; set; }
public virtual string Name { get; set; }
public virtual ICollection<Book> Books { get; set; }
public Author()
{
Books = new Collection<Book>();
}
public void AddBook(Book book)
{
book.Author = this;
Books.Add(book);
}
}
Run Code Online (Sandbox Code Playgroud)
例外:无法设置类型为"Author_4CF5D4EE954712D3502C5DCDDAA549C8E5BF02A0B2133E8826A1AC5A40A15D2A"的属性"Books",因为集合已设置为EntityCollection.
我将Author类更改为此
public class Author
{
public virtual int AuthorId { get; set; }
public virtual string Name { get; set; }
public virtual ICollection<Book> Books { get; set; }
public void AddBook(Book book)
{
book.Author = this;
Books.Add(book);
}
}
Run Code Online (Sandbox Code Playgroud)
例外:对象引用未设置为对象的实例.
无法设置,因为集合已设置为EntityCollection.
这很自然,因为Collection没有设置为new,但是我得到了第一个异常.那么如何在EF中首先使用代码呢?
也许我应该补充说我的It可能会与我的DbSet发生碰撞?
public class EntityContext : DbContext, IUnitOfWork
{
public DbSet<Author> Authors { get; set; }
public DbSet<Book> Books { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.IncludeMetadataInDatabase = false;
}
public void Save()
{
SaveChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
Pan*_*ndo 30
通过阻止实体框架创建更改跟踪代理,从集合属性中删除"虚拟"关键字可解决此问题.但是,对于许多人来说,这不是一个解决方案,因为更改跟踪代理可以非常方便,并且可以在您忘记检测代码中正确位置的更改时帮助防止出现问题.
更好的方法是修改POCO类,以便它们在get访问器中而不是在构造函数中实例化集合属性.这是原始的作者POCO类,经过修改以允许更改跟踪代理创建:
public class Author
{
public virtual int AuthorId { get; set; }
public virtual string Name { get; set; }
private ICollection<Book> _books;
public virtual ICollection<Book> Books
{
get { return _books ?? (_books = new Collection<Book>()); }
set { _books = value; }
}
public void AddBook(Book book)
{
book.Author = this;
Books.Add(book);
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,collection属性不再是自动的,而是具有支持字段.如果您保护setter更好,防止任何代码(代理除外)随后修改这些属性.您会注意到构造函数不再是必需的并被删除.
virtual
关于所有的属性是我的问题..不要理解为什么它有这样的影响当我把它扩展到我的项目,但它是如何...希望这有助于任何人有同样的问题..
Dejan.S上面提到的关于使用'List'初始化集合的问题仍然发生在EF5 RTM和ASP.NET 4.5 RTM中:
但是,如果从主键中删除虚拟关键字(例如上面的screencap中的UserId),它就可以了!所以看起来你的所有属性都可以是虚拟的,除了主键.
归档时间: |
|
查看次数: |
22034 次 |
最近记录: |