3

Assume I have a table with more than 1000000 columns. When I use LINQ To SQL and Entity-Framework all queries will write in c# like below:

EFContext.MyTableName.Where(row=>row.column1==someValue)
                     .Select(...)
                     .FirstOrDefault(...)
                     .Any(...)
                     ...

How to get only and only some columns of entity? Are there any way to get only columns 1 & 2 & 3 among 1000000 columns for example?

Attention:

Type of resulted data should keep after selection, for example if without filtering some columns type of result is Type1 it's very important that after filtering, type of result be Type1 but value of those properties of Type1 which are filtered should be null or default.

Merta
  • 965
  • 1
  • 11
  • 23

2 Answers2

5

To only get a few ROWS you can use:

.Take(3);

To get only some columns you could use:

.Select(x => new MyType() { Column1 = x.Column1, Column2 = x.Column2 })

Note that the object now isn't attached to the objectcontext so it won't be affected by SaveChanges(). But you'll only have selected a few columns and the type will still be correct.

To get your own defaults instead of the framework defaults for variable types, you could modify your constructors type to set the defaults.

middelpat
  • 2,555
  • 1
  • 20
  • 29
  • 1
    Nice approach, but this approach has insufficiency for ABSTRACT classes! There is no way to create instance of abstract classes, what's your suggestion for this new problem? – Merta Mar 11 '14 at 12:09
  • That would be another difficulty. You can consider changing your code so you don't have abstract classes for the types you select. Or perhaps this solution works for you: http://stackoverflow.com/questions/3274241/entity-framework-4-selective-lazy-loading-properties – middelpat Mar 11 '14 at 12:23
  • I read that solution and best answer of it, but there is no thing about abstract classes. – Merta Mar 11 '14 at 12:31
  • I can't change models in code at all! is there any other suggestion?! – Merta Mar 11 '14 at 12:32
  • I can't think of an approach which will fit with abstract classes. The link isn't indeed about abstract classes but just another solution which mayby could've fit your needs. I don't know how strict keeping the type is but you could make a wrapper type which implements your abastract class. then you could use it as: MyAbstractType1 inst = instance_of_MyWrapperType1 – middelpat Mar 11 '14 at 13:42
  • To use the `.Take(3)` method, you first need to order your collection by a certain column. For example: `query.OrderBy(x => x.Column1).Take(3)`. You cant call `.Take(3)` on an unordered `IEnumerable`/`IQueryable` – SynerCoder May 10 '14 at 08:16
1

The only way I know of you get a subset of columns in Entity Framework is to create a new entity class which only has the columns you're interested in and map it to the same table. EF will then not select those columns when querying against that entity. You can also continue to use the full entity when you need it - nothing says you can't have two entity classes mapping to the same table. Or three. Or four...

Depending on the database definition, the subset entity may be entirely insufficient for inserting or updating rows without violating constraints, but it can be a very helpful tool to cut down on the amount of unnecessary data transfer you're doing with your selects, and the time penalty in materialising entities with lots of columns you don't need (which can be very significant).

Matthew Walton
  • 9,809
  • 3
  • 27
  • 36