Добавление случая, когда имя класса для объекта, используемого в структуре сущности, такое же, как имя класса для файла с кодировкой веб-формы.
Предположим, у вас есть веб-форма 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 ()
Нет надежных кросс-платформенных решений этой проблемы. Действительно, бывают ситуации, когда невозможно узнать, какова реальная ширина консоли.
Например, в системе Linux вы обычно можете узнать условные размеры терминала из переменных среды LINES и COLUMNS. Хотя эти переменные автоматически обновляются при изменении размеров окон «эмулятора терминала», это не всегда так. Действительно, в случае удаленной консоли, подключенной по протоколу telnet, нет способа получить фактические размеры терминала в оболочке пользователя.
EDIT: просто добавьте это, если пользователь изменит размеры своего / xterm в Linux после запуска приложения Java, приложение Java не будет уведомлено и не увидит новые измерения, отраженные в его копии переменных среды LINES и COLUMNS!
EDIT 2: Моя ошибка, они bash
переменные оболочки, но не экспортируются в среду по умолчанию. Вы можете «исправить» это, запустив export COLUMNS LINES
перед запуском приложения Java.
Редактирование: см. комментарий @ dave_thompson_085 о ProcessBuilder
, так как это почти наверняка лучший подход.
Еще один ответ упоминал, что вы запускаете tput cols
в скрипте перед началом вашей команды. Но если вы хотите запустить его после того, как Java уже запущена, используя Runtime.getRuntime().exec()
, вы обнаружите, что tput не может разговаривать с вашим терминалом, потому что Java перенаправляет stdout и stderr. В качестве обходного решения, не используемого для всех, вы можете использовать магическое устройство /dev/tty
, которое относится к терминалу текущего процесса. Это позволяет вам запускать что-то вроде этого:
Process p = Runtime.getRuntime().exec(new String[] {
"bash", "-c", "tput cols 2> /dev/tty" });
// Read the output of this process to get your terminal width
Это работает для меня в Linux, но я бы не ожидал, что он будет работать повсюду. Он, надеюсь, будет работать на Mac. Это определенно не будет работать в Windows, хотя это может быть с Cygwin.
ProcessBuilder
, поскольку Java7 (2011) может передать собственный stdin / out / err для Java в дочерний процесс вместо перенаправленных по умолчанию каналов; см. inheritIO()
и redirect*(Redirect.INHERIT)
- что не помогает, если пользователь java
был перенаправлен пользователем, но в этом случае почему вы заботитесь о ширине устройства ввода-вывода, которое вы не используете?
– dave_thompson_085
11 September 2017 в 00:24
Java 6 имеет класс java.io.Console, но, к сожалению, он не имеет требуемой функциональности. Получение ширины окна консоли невозможно в стандартной библиотеке Java и чистой межплатформенной Java.
Вот альтернативная консольная библиотека Java , которая позволяет получить размер экрана , но он включает в себя DLL для Windows. Возможно, вы сможете взять исходный код и скомпилировать часть C в общую библиотеку Linux или Mac OS X, чтобы она также работала на этих платформах.
Я уже работал над этой проблемой. Я использую несколько разных методов. Однако сложно иметь по-настоящему кросс-платформенное решение.
Я попытался сделать что-то вроде этого:
String os = System.getProperty("os.name").toLowerCase();
//Windows
if(os.contains("win")){
System.out.append("Windows Detected");
//set Windows Dos Terminal width 80, height 25
Process p = Runtime.getRuntime().exec("mode 80, 25");
}
//Mac
if(os.contains("mac")){
System.out.println("Macintosh Detected");
//... I dont know...try Google
}
//Linux
if(os.contains("linux")){
System.out.println("Linux Detected");
Вы можете читать / тестировать и добавлять «экспорт COLUMNS» в файл .bashrc в каждом домашнем каталоге Linux для Linux с помощью String .contains ("export COLUMNS") и свойство user.dir.
Это позволит вам загружать столбцы каждый раз при запуске приложения java.
Затем я передам его в файл temp. Например:
try {
ProcessBuilder pb = new ProcessBuilder("bash","-c","echo $COLUMNS >/home/$USER/bin/temp.txt" );
pb.start();
}catch (Exception e) {
System.out.println("exception happened - here's what I know: ");
e.printStackTrace();
System.exit(-1);
}
}
Другой вариант, который у вас есть, - выполнить yor Java.jar с помощью скрипта bash при запуске. Внутри скрипта вы можете использовать «tput cols» для получения ширины. Затем передайте это значение вашему Java-приложению как String [] arg.
Так вот:
//#!/bin/bash
//#clear the screen
clear
//#get the console width and height
c=$[$(tput cols)]
l=$[$(tput lines)]
//#pass the columns, lines and an optional third value as String[] args.
java -jar ~/bin/Plus.jar $c $l $1
почему эта сложная задача с Java? Очевидно, хорошее место для написания хорошего API. Думаю, мы могли бы попробовать Apache.commons.exec?
export COLUMNS
был вызван до начала процесса Java, вы можете просто сделать System.getenv("COLUMNS")
; нет необходимости запускать подпроцесс с ProcessBuilder
.
– dimo414
15 February 2016 в 13:59
Python, похоже, имеет хорошее решение: 11.9.3. Запрос размера выходного терминала . Я бы не задерживал дыхание, ожидая, что это будет доступно в основной Java, но вы могли бы использовать Jython , чтобы сделать доступную функциональность Python.
shutil
документы, это возвращается к os.get_terminal_size()
, который является специфичным для ОС и реализован в C. Использование Jython может работать для некоторых случаев использования, но это довольно тяжелый молот.
– dimo414
15 February 2016 в 14:16
stty -a
в TerminalLineSetting
, а в Windows он подключается к закрытой части библиотеки JAnsi через org.fusesource.jansi.internal.WindowsSupport
.
– dimo414
15 February 2016 в 14:33
Для меня единственный способ получить представление о окне терминала (все еще неверно, когда изменяется размер окна) - использовать команду типа
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", "mode con");
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
. При запуске без части cmd.exe
, это показывает, что команда не найдена. Также обратите внимание на часть redirectError
. Если не используется, тогда будет использоваться размер вывода Java, а не фактический. Только с этой комбинацией можно было захватить фактический размер.
eval `resize`; export COLUMNS
перед вызовом Java под Linux. – Ogre Psalm33 20 September 2011 в 19:54