Reputation: 902
Let's assume the following 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);
}
}
My question is - is there a way in EF to check the two 'is loaded' states? I want to ensure that the books author and the books collection are not loaded only to be disassociated.
I want to write something like:
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);
}
}
Is this possible?
Upvotes: 0
Views: 1443
Reputation: 1758
Keep in mind that I'm not EF expert but maybe it will give you an idea. DbContext.Entry method gives you access to all the information that the DBContext has about an entity. In my understanding you want to know if passed object (as parameter) is already in memory?
Also keep in mind that below method is using 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
}
}
}
}
For navigation properties of type Collection you just use .Collection instead of .Reference.
Upvotes: 0
Reputation: 2989
In your DBContext you can check if an object it's loaded accessing property Local, for example: DBContext.Book.Local
I think that you would be able to do something like this
public IsLoaded(Book book)
{
DBContext.Book.Local.Count(b => b.ID == book.ID) > 0;
}
Upvotes: 1
Reputation: 2967
I know you can check to see if the collection is loaded by using the RelationshipManager
which will work with any entity that contains a relationship, and implements IEntityWithRelationships
.
var result = ((IEntityWithRelationships)(author)).RelationshipManager
.GetRelatedCollection<Books>("FK_Authors_Books", "Books");
if (result.IsLoaded == false)
{
// do something here
}
Note: You'll have to substitute in your proper foreign key name instead of "FK_Authors_Books".
I believe you can also do the same thing with GetRelatedReference
for a single object.
var result = ((IEntityWithRelationships)(book)).RelationshipManager
.GetRelatedReference<Author>("FK_Books_Author", "Author");
if (result.IsLoaded == false)
{
// do something here
}
Upvotes: 1