C# EF检查集合初始化状态

C# EF检查集合初始化状态,c#,entity-framework,collections,lazy-loading,proxy-classes,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 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);        
    }
}
公共类作者
{
公共虚拟字符串名称{get;set;}
公共虚拟列表书{get;set;}
} 
公共课堂用书
{
公共虚拟字符串名称{get;set;}
公共虚拟作者{get;set;}
}
公共类控制器
{
公共图书
{
var author=book.author;//首先检查它是否已加载,而不是调用延迟加载?
author.Books.Remove(book)//检查图书集合是否已加载?
book.Author=null;
Context.Set().Remove(book);
}
}
我的问题是-EF中是否有方法检查两种“已加载”状态? 我希望确保不会仅为了解除关联而加载图书作者和图书集合

我想写一些像:

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);        
    }
}
公共类控制器
{
公共图书
{
if(EF.IsLoaded(book.Author))//是否已(惰性)加载/初始化?
{
if(EF.IsLoaded(book.Author.Books)//是否已(惰性)加载/初始化?
{
book.Author.Books.Remove(book);
}
book.Author=null;
}
Context.Set().Remove(book);
}
}

这可能吗?

我知道您可以使用
RelationshipManager
检查集合是否已加载,它将与包含关系的任何实体一起工作,并实现
ientitywhithrelations

 var result = ((IEntityWithRelationships)(author)).RelationshipManager
       .GetRelatedCollection<Books>("FK_Authors_Books", "Books");

   if (result.IsLoaded == false)
   {
       // do something here
   }

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

我想你可以这样做

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

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

还请记住,下面的方法正在使用

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


出于兴趣,解除关联是什么意思?在上下文中加载或不加载相关对象的事实不会更改关联。DbContext.Entry调用DetectChanges可能需要一段时间(秒或更长)。请确保在调用它之前禁用AutoDetectChangesEnabled。
public IsLoaded(Book book)
{
    DBContext.Book.Local.Count(b => b.ID == book.ID) > 0;
}
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
            }
        }
     }
}