0

Предположим следующие классы:EF проверка коллекции инициализируется состояние

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, чтобы проверить два «загружается» состояния? Я хочу, чтобы автор книг и коллекция книг не были загружены только для того, чтобы их можно было отключить.

Я хочу написать что-то вроде:

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

Возможно ли это?

+0

из интереса, что вы имеете в виду диссоциирует? Тот факт, что связанный объект загружен в контекст или нет, не изменяет связь. –

ответ

1

Я знаю, что вы можете проверить, загружена ли коллекция, используя RelationshipManager, который будет работать с любым объектом, который содержит отношения, и реализует IEntityWithRelationships.

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

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

Примечания: Вы должны заменить в вашем надлежащем внешнем ключе имени вместо «FK_Authors_Books».

Я считаю, что вы можете сделать то же самое с GetRelatedReference для одного объекта.

var result = ((IEntityWithRelationships)(book)).RelationshipManager 
     .GetRelatedReference<Author>("FK_Books_Author", "Author"); 

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

В вашем DbContext вы можете проверить, если объект он загружен доступ свойство Local, например: DBContext.Book.Local

Я думаю, что вы могли бы сделать что-то вроде этого

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

Имейте в виду, что я не эксперт EF, но, возможно, это даст вам представление. Метод DbContext.Entry предоставляет вам доступ ко всей информации, которую DBC-контекст имеет о сущности. В моем понимании вы хотите узнать, находится ли уже в памяти прошедший объект (как параметр)?

Также имейте в виду, что ниже метод использует 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