Why do we have to write SET FMTONLY OFF in stored procedures when using Entity Framework

后端 未结 4 972
时光说笑
时光说笑 2021-02-04 10:51

I recently joined one of the project in my team. They use ASP.NET MVC and MS SQL along with Entity Framework as ORM.

I noticed that each of the stored procedures used in

相关标签:
4条回答
  • 2021-02-04 11:05

    I believe the reason is similar to the one for stored procedures that run from SSRS. In summary, when FMTONLY is active, your stored procedure may have some unexpected results. Hence the reason for explicitly turning it off. For details read Dealing with the Evil of FMTONLY from SSRS

    0 讨论(0)
  • 2021-02-04 11:11

    Having IF(0=1) SET FMTONLY OFF seems like a risky thing to casually do in stored procedures read in by entity framework.

    Entity Framework is the only source of this flag being set as a standard practice that I'm aware of (presumably other ORM's may use it).

    the purpose (as I understand it) is to provide a way to get a procedures return schema without actually touching any data. (some stored procedures you don't want to execute just to update an orm's object model.

    so unless you have a table that is counting the number of times your EF model has been updated (which might be interesting academically)

    for additional information see Stored procedure returns int instead of result set

    the safest way to use ftmonly with entity framework (in my mind) is.. under the following circumstances

    1. if the procedure in question is complex and confuses EF (EF reads the first returned schema, flow logic ignored)
    2. let EF set the flag for you. (I clear it below to exit early)
    3. use always false logic (which would be ignored when FTMONLY is on - interpret this as EF is trying to read schema)
    4. at the beginning of the complex procedure do the following

      if(0=1)  -- if FMTONLY is on this if condition is ignored
      begin
          -- this loop will only be entered if fmtonly is on (ie EF schema read)
          select 
              column1
              ,column2
              ...
              ,columnX
          from whateverA
              cross join whateverB
              ...
              cross join whateverQ
          -- joins don't matter but they might make it easier to get the column definitions
          -- and names you desire.   the important thing here is generating the proper 
          -- return schema... which is as complex as whatever you are trying to return
          where 1=0
      
          set FMTONLY off -- do this so that you can now force an early return since EF
          -- usually only wants the first data set schema...  other orms might
          -- do something different
          return  -- this will be ignored if FMTONLY is still on
      
      end
      
    0 讨论(0)
  • 2021-02-04 11:17

    I have done this temporarily in order to be able to use the designer to map functions to represent the stored procedure in code. The problem is that the designer passes null by default to the procedure to determine the schema. This can sometimes be a problem with stored procs that do validation and throw exceptions etc if null is passed. The Setting you describe gets around this since it returns meta and not the actual data.

    0 讨论(0)
  • 2021-02-04 11:20

    As far as I understand the scenarios, when an EDMX is updated, to return the result set instead of INT for a stored procedure, SET FMTONLY OFF is helpful.

    For ex. "SELECT * FROM @tempTable" is written in a stored procedure,when an edmx is updated for this stored procedure, the type generated in Context.cs file for this stored procedure can be - public virtual int SPName.

    Ideally it must be: public virtual ObjectResult SPName

    To attain the above result, we have to use SET FMTONLY OFF.

    We are avoiding the return type as INT and making it as type of resultset: LINK to know how to use: http://www.sandeepknarware.in/?p=247

    0 讨论(0)
提交回复
热议问题