6

I have a stored procedure in my sqlserver database which is returning multiple resultset.

I am using following link from msdn to read multiple resultset from SP in entity framework.

https://msdn.microsoft.com/en-us/library/jj691402(v=vs.113).aspx

To read data, I need to have DBSets in xyzDBContext class for each of the resultsets.

Model Class:

public class AreaView
{
    public String Area { get; set; }
    public String Weight { get; set; }

}

DBContext:

 public class EnsembleAPIContext : DbContext
    {
       public DbSet<AreaView> area {get; set;}

// I want to prevent this table from getting created in db

      }

This is how I am reading resultset and mapping it with above created dbset.

 reader.NextResult();
                    var contributionArea = ((IObjectContextAdapter)db)
                       .ObjectContext
                       .Translate<ContributionArea>(reader, "area ", MergeOption.AppendOnly);

What I need to do is I want to create entity for these resultsets, but I dont want framework to create tables for these entities in database.

Note: Reason for doing this is, resultset which is returned by sp doesnt have a primary key, so suppose we can have a valid table created using entity without PK.

Is this possible?

Any help is appreciated.

Dheeraj Kumar
  • 3,917
  • 8
  • 43
  • 80
  • 1
    Why do you _need_ a DbSet? You generally create a method on your DbContext to get data from an SP, see https://stackoverflow.com/questions/20901419/how-to-call-stored-procedure-in-entity-framework-6-code-first – CodeCaster Aug 03 '17 at 11:51
  • @CodeCaster SP is not created by Codefirst. It already exists. I am just calling it from Code. – Dheeraj Kumar Aug 03 '17 at 11:53
  • 1
    I'm afraid you didn't understand my comment. It has nothing to do with code first. You use `DbSet` for tables, not for SPs. – CodeCaster Aug 03 '17 at 11:58
  • @CodeCaster Did you check that msdn link, I am following that to read multiple resultset. Now while reading resultset, we need to mention entity for which resultset is to be mapped. Now here I want to create an entity just for this mapping purpose, and not create table in database for that. I hope this is clear – Dheeraj Kumar Aug 03 '17 at 12:00
  • 3
    No, I didn't read that link. Now I did, and I still don't see the need for a DbSet. Read [ask] and include all relevant details in your question. – CodeCaster Aug 03 '17 at 12:04
  • @CodeCaster How else do I create EntitySet to map resultset with?? What other details you need, please let me know. – Dheeraj Kumar Aug 03 '17 at 12:13

2 Answers2

20

The answer to "If we can skip creating tables in database with Entity framework is": Yes

Use [NotMapped] attribute.

 [NotMapped]
   public class Employee
    {
        public int ID { get; set; }
        public String name { get; set; }
    }

You can use this model for general purpose and table wont be created for this in database.

Another way of doing this is

In OnModelCreating() method

modelBuilder.Ignore<Employee>();

This way DBContext will ignore creating table for this model.

Dheeraj Kumar
  • 3,917
  • 8
  • 43
  • 80
6

Can we create a DBSet<> without creating corresponding table in database

No. DbSet<T> represents a real database table or view.

To read data, I need to have DBSets in xyzDBContext class for each of the resultsets.

You don't. The ObjectContext.Translate method can be used to map DbReader to any class. The linked example is using entity types, but there is another Translate method overload which works for any type as described in Directly Executing Store Commands MSDN topic - Materializing the Result Type section.

With that being said, remove the DbSet from your context and use something like this:

var areaView = ((IObjectContextAdapter)db).ObjectContext.Translate<AreaView>(reader);
Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343
  • Thank you for clarifying. So EF will create tables for the model classes?? So how doees it identity them? Just curious. – Dheeraj Kumar Aug 03 '17 at 13:33
  • There are several ways used by EF to discover class as being *entity*. One of them is when you have defined `DbSet` :) Others are through navigation properties or flient API calls like `modelBuilder.Entity()` etc. – Ivan Stoev Aug 03 '17 at 13:36
  • I found the way to skip creating tables. Please check my answer. Thanks for your time. – Dheeraj Kumar Aug 04 '17 at 09:24
  • 2
    Yes, you can tell EF to ignore the *entity*, but then `DbSet` makes no sence - there is nothing you can do with it. It will be confusing and most likely throw exceptions if you try using it in a query or something. So I stay on my point in the answer. – Ivan Stoev Aug 04 '17 at 09:28
  • But in my situation where I need models just to map resultset, there is not point to create dbset and tables. Just have to use models, in these cases ignoring will be useful. :) – Dheeraj Kumar Aug 04 '17 at 09:37
  • Not sure I follow. In your case you have plain classes (call them models or not), which are just to map resultset. There is no need to add dbsets for them in your context, hence no need to ignore :) – Ivan Stoev Aug 04 '17 at 09:42
  • Yeah. those are plain classes, and still EF was creating tables for these too which I wanted to skip. Thats why I had asked you how EF select classes. :) – Dheeraj Kumar Aug 04 '17 at 09:50
  • Did you remove the dbsets? They shouldn't be treated as entity if you did so, except if you reference them from collection or simple navigation property of another entity, in which case your answer applies. But it has nothing in common with your original question for `DbSet<>` (which as I see now you changed, thus invalidating my answer, which I believe was not correct). If you do not have `DbSet` and EF tries to create a table, that's totally different issue and should have been asked in a new question. – Ivan Stoev Aug 04 '17 at 10:15
  • Yes. I did remove DbSet. and yes still plain classes being referred in other entities. That's the reason for ignoring. I appreciate your time and help with clarifications. :) – Dheeraj Kumar Aug 04 '17 at 10:32
  • One use case for ignoring a model is if it's mapped to something that your DB context isn't responsible for but you want to manage the objects and data in your context. i.e. a legacy application table or table created by another application or 3rd-party source – Bron Davies Mar 06 '18 at 17:55
  • @BronDavies The question was not whether you can ignore model or not (of course you can). The point is that you don't need `DbSet` (which will not work for ignored entity anyway) in order to materialize SP result. OP is self answering a question they never asked. And, ha-ha, just saw this https://stackoverflow.com/questions/49136316/how-to-create-dbset-for-ignored-enitity – Ivan Stoev Mar 06 '18 at 18:42