Как обновить только выбранные поля (анонимный тип для сильного типа) в Entity Framework - PullRequest
1 голос
/ 15 марта 2011

Итак, в моей сущности есть большие столбцы, которые мне не нужны в моем представлении. Чтобы не загружать большие столбцы, я использую анонимный тип с приведением к сильному.

       _ctx = new hModelContainer();
       var skAnonym = from s in _ctx.Sketches
                         where s.SketchStatus.Id == 0
                         select new
                         {
                             s.Id,
                             s.Number,
                             s.Author,
                             s.SketchStatus,
                             s.Title,
                             s.Comments
                         };

            var skStrong = skAnonymt.AsEnumerable().Select(s =>
                         new Sketch
                         {
                             Id = s.Id,
                             Number = s.Number,
                             Author = s.Author,
                             SketchStatus = s.SketchStatus,
                             Title = s.Title,
                             Comments = s.Comments
                         });

            _sketchs = skStrong.ToList();

, затем я обновляю свою коллекцию _sketchs в WPF View и хочу сохранить ее в БД. Если бы я попытался сделать это напрямую _ctx.SaveChanges(); У меня есть исключение

"... невозможно вставить NULL в noNulleable поле TextXML "

и TextXML - это имя столбца, который я не загружал из БД, потому что он большой, и он мне не нужен в моем представлении. Так как же обновить существующую сущность из моего представления?

Ответы [ 2 ]

2 голосов
/ 15 марта 2011

Если вы хотите избежать загрузки больших полей, отметьте разбиение таблицы . Это сэкономит вам много усилий, потому что вы в основном будете работать только с сущностью, которая не будет содержать эти поля.

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

using (var context = new MyContext())
{
    context.Attach(sketch);
    ObjectStateEntry entry = context.ObjectStateManager.GetObjectStateEntry(sketch);
    entry.SetModifiedProperty("Number");
    ...
    context.SaveChanges();
}
0 голосов
/ 15 марта 2011

Вот что у меня сработало.Я создал тестовую таблицу следующим образом:

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[MyTable]') AND type in (N'U'))
DROP TABLE [dbo].[MyTable]
GO

CREATE TABLE [dbo].[MyTable](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Data1] [varchar](50) NOT NULL,
    [Data2] [varchar](50) NOT NULL,
 CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

INSERT INTO [dbo].[MyTable] (Data1,Data2) VALUES ('Row 1 - Data 1', 'Row1 - Data 2')
INSERT INTO [dbo].[MyTable] (Data1,Data2) VALUES ('Row 2 - Data 1', 'Row2 - Data 2')
GO

В VS я импортировал эту таблицу с помощью мастера в модель Entity.Затем я написал следующий код:

        TestEntities ctx = new TestEntities();
        var data = from d in ctx.MyTables select new { d.Id, d.Data1 };
        var data2 = data.AsEnumerable().Select(x => new MyTable(){Id = x.Id, Data1 =  x.Data1 });
        var data3 = data2.ToList();

        foreach (var item in data3)
        {
            ctx.MyTables.Attach(item);
        }

        data3[0].Data1 = "Hello";            

        ctx.SaveChanges();

После выполнения этого кода я просмотрел базу данных и проверил, что значение изменилось на «Hello».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...