New Posts New Posts RSS Feed: Stored Procedures and QueryStrategy.DataSourceOnly
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

Stored Procedures and QueryStrategy.DataSourceOnly

 Post Reply Post Reply
Author
sebma View Drop Down
Groupie
Groupie
Avatar

Joined: 19-Aug-2008
Location: Singapore
Posts: 66
Post Options Post Options   Quote sebma Quote  Post ReplyReply Direct Link To This Post Topic: Stored Procedures and QueryStrategy.DataSourceOnly
    Posted: 26-Jun-2009 at 4:41am

Hello all,

Currently we have data grid populated by view results returned from store procedures.
We want the grid to refresh with latest information from database.
I tried the following by apparent the entity manager is not re-executing the stored proc from db because subsequent calls shows no sql statements in sql profiler. (see the codes commented out).
 
          int intTemporalType = (int)type;
          IList<ViewTrainingsByGroup> retList = new List<ViewTrainingsByGroup>();
          // commented because QueryStrategy.DataSourceOnly has no effect
          //StoredProcQuery spQuery = em.GetTrainingsByGroupQuery(trainingGroupId, timePoint, intTemporalType, range.Start, range.End);
          //StoredProcQuery spQuery = new StoredProcQuery(typeof(DomainModel.ViewTrainingsByGroup));
          //spQuery.ProcedureName = "GetTrainingsByGroup";
          //spQuery.Parameters.Add(new QueryParameter("TrainingGroupId", trainingGroupId));
          //spQuery.Parameters.Add(new QueryParameter("TimePoint", timePoint));
          //spQuery.Parameters.Add(new QueryParameter("TemporalType", type));
          //spQuery.Parameters.Add(new QueryParameter("TimeRangeStart", range.Start));
          //spQuery.Parameters.Add(new QueryParameter("TimeRangeEnd", range.End));
          //if (refetchFromDatabase)
          //{
          //    QueryStrategy qs = spQuery.QueryStrategy;
          //    retList = spQuery.With(QueryStrategy.DataSourceOnly).Execute().Cast<ViewTrainingsByGroup>().ToList();
          //}
          //else
          //{
          //    retList = em.ExecuteQuery(spQuery).Cast<ViewTrainingsByGroup>().ToList();
          //}
          retList = em.GetTrainingsByGroup(trainingGroupId, timePoint, intTemporalType, range.Start, range.End).ToList();
 
Also, when entity is updated but not refreshed in grid, the following exception is thrown and I have no idea yet :(
 
Exception thrown during save:
Unable to update the EntitySet 'ViewTrainingsByGroup' because it has a DefiningQuery and no <UpdateFunction> element exists in the <ModificationFunctionMapping> element to support the current operation.
 
Any help is appreciated.
 
Thanks.
 
 
 

 
Back to Top
kimj View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 1391
Post Options Post Options   Quote kimj Quote  Post ReplyReply Direct Link To This Post Posted: 26-Jun-2009 at 4:59pm
A StoredProcQuery is by definition a data source only query, since the procedure cannot be executed against cache.  I can't reproduce the issue you see here - if an exception has not been thrown then the query should have gone to the database.    Check the debug log to see if that has any helpful diagnostics.  What DevForce version are you running, and are you running in n-tier mode?
 
As for the update problem, entities backed by a stored proc are also read only - this is an Entity Framework limitation.  As the error message states, you need to define an UpdateFunction in the EDMX to tell EF how to handle the update.  Check out the MSDN for more information - http://msdn.microsoft.com/en-us/library/bb896279.aspx.
 
Back to Top
sebma View Drop Down
Groupie
Groupie
Avatar

Joined: 19-Aug-2008
Location: Singapore
Posts: 66
Post Options Post Options   Quote sebma Quote  Post ReplyReply Direct Link To This Post Posted: 27-Jun-2009 at 7:37am
Hello Kim!
 
Indeed, the save changes exception is due to EF "limitation", I have to define an UpdateFunction.
As quoted:
Unfortunately, when you generate a model including a view, the mapping to that view gets setup with a DefiningQuery which is a way to signal to the framework that standard DML operations to the view won't work (because in the general case views don't support DML).  The normal expectation is that you would write stored procedures for the create, update and delete operations and map them to the entityset so that the view can be used for reads and the stored procedures for writes.
 
After I defined the update stored proc, even with an no-op like the following stored proc, there is no more exception:
CREATE PROCEDURE [dbo].[NOOPUpdate]
AS
PRINT 'HELLO WORLD';
 
Now back to the stored proc query. It made no difference whether I run in 2-tier or N-tier BOS. The debug log is attached (DebugLog_SP.zip). The log did show that the stored proc was executed.
Initially it really seems strange to me. If you look at other zip file with 2 screen shots (IdeaBladeForumTopic_Stored Procedures_and_QueryStrategy.zip).
When it breaks at the breakpoint, I look at my table in SQL Server (IdeaBladeForumMyTopic1.jpg, Title="NEW123" and Version="NEW123"), the Version and Title columns had indeed been updated after save changes. But proceeding next line after the stored proc was executed, retList[1] still shows the old values (IdeaBladeForumMyTopic2.jpg, Title="NEW12" and Version="NEW12").
 
One has to know that the view results returned by the stored proc consists of SQL "JOINS" from a few tables, where LEFT JOIN equates to nullable columns in the view and hence cannot be inferred as entity keys. I have to change the sql view (not yet the stored proc that returns the same columns as the view) to be INNER JOINs instead, to make the columns non-nullable, for example:
 
SELECT
t.GroupId 'TrainingGroupId',
tg.Name 'TrainingGroupName',
t.InternalId 'TrainingInternalId',
t.ID 'TrainingID',
t.ExpiryDate 'TrainingExpiryDate',
tv.Title,
tv.Version,
tv.EffectiveFrom,
tv.EffectiveTo,
tv.InternalId 'TrainingVersionId'
FROM Trainings t
INNER JOIN TrainingGroups tg ON tg.InternalId = t.GroupId AND tg.Status = 99
--LEFT JOIN TrainingVersions tv ON tv.TrainingId = t.InternalId AND tv.Status = 99
INNER JOIN TrainingVersions tv ON tv.TrainingId = t.InternalId AND tv.Status = 99
 
Without the above changes, the entity manager cache or query cache seems not to be refreshed unless there are differences in values of the keys. These seems strange because columns from views can come from various tables and that there is no guarantee that all columns are non-nullables.
 
 
Best regards,
Sebastian
 
 
 
 
 
Back to Top
kimj View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 1391
Post Options Post Options   Quote kimj Quote  Post ReplyReply Direct Link To This Post Posted: 27-Jun-2009 at 2:18pm
Hi Sebastian,
 
Merging of StoredProcQuery results back into the EntityManager cache follows the same rules as for any other type of query, and uses the MergeStrategy in effect for the query.  The EntityManager, and everything else in DevForce,  is completely unaware of how the stored proc is defined so I don't think that's the issue. 
 
Check the MergeStrategy in effect.  Maybe the EntityState of the changed (and saved?) items is still set to Modified and you're using a PreserveChanges strategy, which would cause the retrieved item(s) not be be merged into cache.  If this is the case and items have a Modified EntityState but have been saved, then that's a separate issue - and please let me know about it.
 
Kim
Back to Top
sebma View Drop Down
Groupie
Groupie
Avatar

Joined: 19-Aug-2008
Location: Singapore
Posts: 66
Post Options Post Options   Quote sebma Quote  Post ReplyReply Direct Link To This Post Posted: 28-Jun-2009 at 8:53pm
Hi Kim,
 
The MergeStrategy in effect was OverWriteChanges (see attached pic). I can see there is this thing called EntityReferenceStrategy, with LoadStrategy = Lazy. However, we are executing a stored proc that returns a view, not entity, so I do not know if and how this could have any effect.
 
 
Sebastian
Back to Top
kimj View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 1391
Post Options Post Options   Quote kimj Quote  Post ReplyReply Direct Link To This Post Posted: 29-Jun-2009 at 10:51am
I haven't seen this problem in testing.  My only other thought would be to check the EntityKey of the ViewTrainingsByGroup entity type.  Queried items are merged into cache by key, so maybe the key definition is not allowing the entities to be matched and reloaded.  Do a FindEntities<ViewTrainingsByGroup>(allstates) to see what's actually in cache after the query runs the second time.
Back to Top
sebma View Drop Down
Groupie
Groupie
Avatar

Joined: 19-Aug-2008
Location: Singapore
Posts: 66
Post Options Post Options   Quote sebma Quote  Post ReplyReply Direct Link To This Post Posted: 29-Jun-2009 at 8:13pm

I believe this is exactly the case - the key definition is not allowing the entities to be matched and reloaded.

If you looked at the attached pic, the unmodified list is containing the old values. All the other states' lists are empty, even when the changes had already been committed to database.
 
As mentioned above in this post, the view comes from joins of 3 tables for instance, with some columns that are nullables, including the Title and Version columns. These columns therefore cannot be keys (see table mappings).
Title and Version columns were edited and saved. Note that there was no change in key values.
 
We seem to have already the right settings for fetch and merge strategy.
What's confusing is, is there anyway to just ask the EntityManager to just fetch directly from datasource?
 
Back to Top
kimj View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 1391
Post Options Post Options   Quote kimj Quote  Post ReplyReply Direct Link To This Post Posted: 30-Jun-2009 at 10:03am
The EntityManager does fetch directly from the datasource, and only the datasource, when using a StoredProcQuery.  I am unable to piece together what may be happening here - although the inclusion of the string "TrainingId" in the key is a bit suspicious.  If you think there's a DevForce problem please send support@ideablade.com an entire sample application, with all support files, which exhibits the problem.  
Back to Top
sebma View Drop Down
Groupie
Groupie
Avatar

Joined: 19-Aug-2008
Location: Singapore
Posts: 66
Post Options Post Options   Quote sebma Quote  Post ReplyReply Direct Link To This Post Posted: 30-Jun-2009 at 6:58pm

Will do, I'll send a sample project in a week or so as I have some dead lines currently.

Thanks Kim!
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down