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