Добавление случая, когда имя класса для объекта, используемого в структуре сущности, такое же, как имя класса для файла с кодировкой веб-формы.
Предположим, у вас есть веб-форма Contact.aspx, чей класс codebehind Свяжитесь с вами, и у вас есть имя объекта Contact.
Затем следующий код вызовет исключение NullReferenceException при вызове context.SaveChanges ()
Contact contact = new Contact { Name = "Abhinav"};
var context = new DataContext();
context.Contacts.Add(contact);
context.SaveChanges(); // NullReferenceException at this line
Ради полноты класса DataContext
public class DataContext : DbContext
{
public DbSet Contacts {get; set;}
}
и класс сущности контакта. Иногда классы сущностей являются частичными классами, так что вы можете распространять их и в других файлах.
public partial class Contact
{
public string Name {get; set;}
}
Ошибка возникает, когда оба класса entity и codebehind находятся в одном и том же пространстве имен. Чтобы исправить это, переименуйте класс сущности или класс codebehind для Contact.aspx.
Причина. Я все еще не уверен в причине. Но всякий раз, когда какой-либо из классов сущностей расширяет System.Web.UI.Page, возникает эта ошибка.
Для обсуждения рассмотрим NullReferenceException в DbContext.saveChanges ()
Вы попали в ловушку с использованием записей.
Рассмотрите этот код:
function Test: TTest;
begin
...
end;
Test.a := 1;
Что ваш код выглядит как компилятор, на самом деле это:
TTest temp := Test;
temp.a := 1;
Компилятор сообщает вам, с сообщением об ошибке, что назначение бессмысленно, поскольку оно будет присваивать новое значение только временному значению записи, которое будет немедленно забыто.
Кроме того, @List[10]
недействителен, потому что List[10]
снова возвращает только временное значение записи, поэтому запись адреса этой записи является довольно бессмысленной.
Однако чтение и запись всей записи в порядке.
Итак, чтобы подвести итог:
List[10] := A; <- writing a whole record is OK
List[10].a:=1; <- List[10] returns a temporary record, pointless assignment
P:=@List[10]; <- List[10] returns a temporary record, its address is pointless
Если вы хотите хранить записи, динамические массивы более подходят для их обработки:
type TTest = record a,b,c : Integer end;
type TTestList = array of TTest;
var List:TTestList;
A:TTest;
P:Pointer;
....
....
SetLength( List, 20 );
List[10] := A; //<- OK
List[10].a := 1; //<- Ok
P := @List[10]; //<- Not advised (the next SetLength(List,xx) will blow the address away),
// but technically works
Если вам нужно добавить методы для управления этими данными, вы можете сохранить этот массив в качестве поля класс и добавьте свои методы в этот класс.
A := List[10];
A.a := 1;
list[10] := A;
Вам не нужно делать это с помощью объектов, потому что они являются ссылочными типами (доступ через указатель, который компилятор управляет внутренне, чтобы сохранить его из ваших волос), но записи являются типами значений, поэтому он не делает Так работать.
Если вам нужно манипулировать объектами в этой форме, лучше использовать TObjectList вместо TList и определить структуру как класс, а не запись:
type TTest = class a,b,c:Integer end;
var List:TObjectList<TTest>;
A:TTest; // A is an object so there's no need for a pointer
....
....
List.Add(TTest.Create);
List.Last.a := 1;
A:=List.Last;