Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Базы данных под .NET > LINQ to SQL: добавление новой строки в БД


Автор: RWander 28.12.2007, 20:44
начал изучать LINQ.
Создал таблицу:
Код

CREATE TABLE Student
{
ID int primary key,
Name nvarchar(100),
Year int
}


Создаю класс, который будет хранить одну строку таблицы Student:
Код

using System.Linq;
using System.Data.Linq;
using System.Data.Linq.Mapping;

[Table(Name = "Students")]
public class Student
{
       [Column(Name = "ID", IsPrimaryKey = true)]
       public int ID;
       [Column]
       public string Name;
       [Column]
       public int Year;
}


теперь пытаюсь добавить новую строку в таблицу:
Код

// DataContext takes a connection string. 
 DataContext db = new DataContext("Database1.sdf");
// Get a typed table to run queries.
Table<Student> students = db.GetTable<Student>();
students.InsertOnSubmit(new Student {  Name = "Роман",  Year = 20 }); //поле ID не указываю, так как оно автоинкрементное
try
{
    db.SubmitChanges();
}
catch(Exception e)
{
     Console.WriteLine(e.Message);
}


выдает ошибку:
Цитата

The column cannot be modified. [ Column name = ID]


не могу понять, где ошибка

Автор: Idsa 29.12.2007, 03:17
Цитата(RWander @  28.12.2007,  20:44 Найти цитируемый пост)
//поле ID не указываю, так как оно автоинкрементное

Автоинкрементное оно у тебя в СУБД.

Автор: RWander 29.12.2007, 09:39
если я пишу 
Код

students.InsertOnSubmit(new Student {  ID=34 , Name = "Роман",  Year = 20 });

то выдается та же ошибка

Автор: mr.DUDA 29.12.2007, 11:44
Попробовать -1 или 0.

Автор: RWander 29.12.2007, 11:57
Цитата(mr.DUDA @  29.12.2007,  13:44 Найти цитируемый пост)
Попробовать -1 или 0.

Если вы имеете ввиду присвоить ID = -1, то все равно та же ошибка

Автор: JimCary 28.1.2008, 08:42
А не существует ли возможности при создании класса Student задать, что поле ID автоинкрементное, может тогда все заработает.

Автор: bullterier 15.2.2008, 16:41
попробуй в атрибуте [Column(....)] добавить : IsDbGenerated = true

Автор: xni 24.7.2008, 15:51
Аналогичная ошибка. Вы разобрались?

Вот что интересно -- просматриваю лог свего DataContext и вот что вижу:

Код

INSERT INTO [Таблица2]([Status_name])
VALUES (@p0)

SELECT CONVERT(Int,SCOPE_IDENTITY()) AS [value]
-- @p0: Input String (Size = 9; Prec = 0; Scale = 0) [NewStatus]


В таблице всего 2 поля: ID (счётчик) и Statis_name (текст).
Может быть дело в том, что я работаю с базой данных Access? Может с SQL Server будет иначе?

Автор: Idsa 24.7.2008, 16:14
Цитата(RWander @  29.12.2007,  00:44 Найти цитируемый пост)
The column cannot be modified. [ Column name = ID]

Судя по всему, в базе Id объявлен как Identity. Тогда при объявлении Id не хватает http://msdn.microsoft.com/en-us/library/system.data.linq.mapping.columnattribute.isdbgenerated.aspx (обратите внимание на примечание и пример).

А в этом же примере происходит следующее:
1. При создании объекта сущности в Id хранится 0 (значение по умолчанию для int)
2. При добавлении сущности составляется запрос на вставку значений во все поля, кроме тех, которые помечены атрибутом IsDbGenerated. Т. к. Id не помечен этим атрибутом, получится примерно следующий запрос:
Код

INSERT INTO MyTable (Id, Name, Year) VALUES (0, someValue, someValue);

3. Естественно, на попытку вставить значение в Identity поле Sql Server среагирует Exception'ом.

xni, Вы тоже ручками генерировали модель? Генерируйте дизайнером, не усложняйте себе жизнь.
Если Вы только начинаете проект или изучаете для себя, взгляните лучше на Entity Framework. Гораздо более мощная и перспективная ORM.

Автор: xni 24.7.2008, 18:34
Благодарю!

А со своей проблемой, я кажется, разобрался -- не знаю верно ли я понял или нет, но в Access 2007 поле типа "счётчик" всё равно трбует заполнения. Когда было выставлено IsDbGenerated = true оно не передавало значение счётчика, из-за чего возникала ошибка.

Теперь ввожу ID вручную. Это неудобно, но работает...

Автор: PashaPash 24.7.2008, 20:48
xni, Linq to SQL вроде не поддерживает access вообще. Странно что хоть как-то работает.

Автор: Idsa 25.7.2008, 15:55
Цитата(xni @  24.7.2008,  22:34 Найти цитируемый пост)
А со своей проблемой, я кажется, разобрался -- не знаю верно ли я понял или нет, но в Access 2007 поле типа "счётчик" всё равно трбует заполнения. Когда было выставлено IsDbGenerated = true оно не передавало значение счётчика, из-за чего возникала ошибка.

Если Вы используете Access, то Вам прямая дорога к Entity Framework или nHibernate.

Цитата(PashaPash @  25.7.2008,  00:48 Найти цитируемый пост)
xni, Linq to SQL вроде не поддерживает access вообще. Странно что хоть как-то работает. 

Поддерживает. Правда с рядом ограничений. Вот здесь есть обсуждение: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2120679&SiteID=1
Фишка в том, чтобы передать конструктору DataContext'а OleDbConnection. Правда, т. к. это нечто вроде workaround'а, стабильная работа не гарантируется: в частности, не поддерживаются некоторые типы.

Автор: PashaPash 25.7.2008, 16:57
Цитата(Idsa @  25.7.2008,  15:55 Найти цитируемый пост)
Поддерживает. Правда с рядом ограничений.

Можно заставить заработать - еще не значит что он поддерживает. По ссылке же прямо так и написано. Т.е. что-то работать будет, но в живом проекте лучше не использовать.

Автор: Idsa 25.7.2008, 17:22
PashaPash, я же так и написал: есть ряд ограничений. Естественно, в реальных проектах использовать Linq To Sql с Access не имеет смысла.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)