Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Record with big data field - update without fetching?

I have a table with image as varbinary(max) and with another data (with another types) which are more compact. I want to update another data but not image. In cycle (i.e. all records) with filter to choose records to update. I find various solutions but all of them use fetching the whole record(s) into context or attaching existing record (i.e. fetched or created sometime before) to context. Saying "fetched or created sometime before" I mean the whole record with all fields are presented - not cutted off image or another "unnecessary" fields.

Is there a way to update records without fetching any unnecessary data (varbinary image for example) but through EF? Maybe just fetching whatever lightweight POCO object without all the fields but only with those I need? Or this class of tasks lays outside the EF's assignment and I have to use plain SQL?

Well, just simple example:

DB table:

create table Weed
(
    Id int identity(1,1) not null,
    Name nvarchar(100) not null,
    Description nvarchar(max) null,
    Image varbinary(max) null
)

EF's POCO

public partial class Weed
{
    public Weed()
    {}

    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public byte[] Image { get; set; }
}

I want to update the description without fetching the whole weed (especially the image field), and for weeds whose names start with "A", for example.

like image 354
user808128 Avatar asked Oct 09 '13 15:10

user808128


1 Answers

In Entity Framework if you want to do an update without first getting the entity you should be able to use the DbContext.Entry method like so:

var model = new MyModel() { Id = id, OtherData = data };
using (var db = new MyEfContextName())
{
    db.MyModels.Attach(model);
    db.Entry(model).Property(x => x.OtherData).IsModified = true;
    db.SaveChanges();
}

This should tell EF to generate the appropriate UPDATE statement for you without having to SELECT the entity data at all.

On the other hand if you need to do a brief SELECT first in order to retrieve the Id for example, you could use an anonymous type when you select with Linq to Entities:

var existingData = db.MyModels.Where(x => x.SomeParameter == someValue).Select(x => new { Id = x.Id, OtherData = x.OtherData }).SingleOrDefault();

This will generate a SELECT statement which only selects the data you need and output it to an anonymous type.

And I should note that if you are doing complex queries or you are looking for efficiency then don't be afraid to use DbContext.Database.SqlQuery or DbContext.Database.ExecuteSqlCommand. Entity Framework won't support everything you might want to do and it's OK to go around it when needed.

like image 70
Richard Tozier Avatar answered Sep 23 '22 12:09

Richard Tozier