EF检查集合初始化状态

时间:2014-10-28 01:40:55

标签: c# entity-framework collections lazy-loading proxy-classes

让我们假设以下课程:

public class Author
{
    public virtual string Name { get; set; }
    public virtual List<Book> Books { get; set; }
} 

public class Book
{
    public virtual string Name { get; set; }
    public virtual Author Author { get; set; }
}

public class Controller
{
    public void DeleteBook(Book book)
    {
        var author = book.Author; //first check if it is loaded, not to invoke lazy loading?
        author.Books.Remove(book) //check if the books collection is loaded?
        book.Author = null;

        Context.Set<Book>().Remove(book);        
    }
}

我的问题是 - 在EF中是否有办法检查两个“已加载”#39;状态? 我想确保书籍作者和书籍收藏品不会被加载,只是为了解除关联。

我想写一些类似的东西:

public class Controller
{
    public void DeleteBook(Book book)
    {
        if (EF.IsLoaded(book.Author)) //has it been (lazy) loaded / initialized?
        {
             if (EF.IsLoaded(book.Author.Books) //has it been (lazy) loaded / initialized?
             {
                 book.Author.Books.Remove(book);
             }
             book.Author = null;
        }
        Context.Set<Book>().Remove(book);        
    }
}

这可能吗?

3 个答案:

答案 0 :(得分:1)

我知道您可以使用RelationshipManager检查集合是否已加载,该IEntityWithRelationships将与包含关系的任何实体一起使用,并实现 var result = ((IEntityWithRelationships)(author)).RelationshipManager .GetRelatedCollection<Books>("FK_Authors_Books", "Books"); if (result.IsLoaded == false) { // do something here }

GetRelatedReference

注意:您必须使用正确的外键名称替换“FK_Authors_Books”。

我相信你也可以用 var result = ((IEntityWithRelationships)(book)).RelationshipManager .GetRelatedReference<Author>("FK_Books_Author", "Author"); if (result.IsLoaded == false) { // do something here } 为一个对象做同样的事情。

{{1}}

答案 1 :(得分:1)

在您的DBContext中,您可以检查它加载的对象是否访问属性Local,例如:DBContext.Book.Local

我认为你可以做这样的事情

public IsLoaded(Book book)
{
    DBContext.Book.Local.Count(b => b.ID == book.ID) > 0;
}

答案 2 :(得分:0)

请记住,我不是EF专家,但也许它会给你一个想法。 DbContext.Entry方法使您可以访问DBContext有关实体的所有信息。根据我的理解,你想知道传递的对象(作为参数)是否已经在内存中了?

另请注意,以下方法正在使用explicit loading

public class Controller
{
    public void DeleteBook(Book book)
    {
        // assuming that you're working on context directly and need to dispose it
        using (var context = new YourContext())
        {
            var entry = context.Entry(book);
            // Will tell you if Author navigation property is loaded
            bool isLoaded = entry.Reference(x => x.Author).IsLoaded();

            if (isLoaded != false)
            {
                // do when Author navigation property is loaded
            }
            else
            {
                // do when Author navigation property is not loaded
            }
        }
     }
}

对于Collection类型的导航属性,您只需使用.Collection而不是.Reference。

http://msdn.microsoft.com/en-us/library/system.data.objects.dataclasses.relatedend.isloaded(v=vs.110).aspx