Значение присваивания, левая сторона не может быть назначена [дублировать]

Добавление случая, когда имя класса для объекта, используемого в структуре сущности, такое же, как имя класса для файла с кодировкой веб-формы.

Предположим, у вас есть веб-форма 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 ()

10
задан Astronavigator 30 April 2010 в 21:38
поделиться

4 ответа

Вы попали в ловушку с использованием записей.

Рассмотрите этот код:

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
7
ответ дан Lasse Vågsæther Karlsen 28 August 2018 в 07:45
поделиться
  • 1
    Однако элементы свойств читаются и записываются, и я думаю, что delphi может понять, что Items [1] .a: = 123 meens Элементы [1]: = TType (123, oldval2, oldval3) – Astronavigator 30 April 2010 в 21:57
  • 2
    Но это не так ... Важная часть - это не то, что делает компилятор , но что он на самом деле делает . – Lasse Vågsæther Karlsen 30 April 2010 в 21:59
  • 3
    @Astronavigator: Да, свойство R / W, но вы не получаете доступ к полю напрямую. Он просто возвращает копию поля. Проверьте ответ Мейсона, чтобы обойти это. – Ken Bourassa 30 April 2010 в 22:19

Если вы хотите хранить записи, динамические массивы более подходят для их обработки:

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

Если вам нужно добавить методы для управления этими данными, вы можете сохранить этот массив в качестве поля класс и добавьте свои методы в этот класс.

2
ответ дан LeGEC 28 August 2018 в 07:45
поделиться
A := List[10];
A.a := 1;
list[10] := A;

Вам не нужно делать это с помощью объектов, потому что они являются ссылочными типами (доступ через указатель, который компилятор управляет внутренне, чтобы сохранить его из ваших волос), но записи являются типами значений, поэтому он не делает Так работать.

9
ответ дан Mason Wheeler 28 August 2018 в 07:45
поделиться
  • 1
    это простой и прочный способ. но когда размер записи очень большой, стек переполняется из-за локальной переменной A, и если это работает в цикле или циклах, это очень медленно. – JO SeongGng 9 July 2015 в 04:18

Если вам нужно манипулировать объектами в этой форме, лучше использовать 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;
0
ответ дан Ziggy Crueltyfree Zeitgeister 28 August 2018 в 07:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: