I’m somewhat new to using LINQ and Entity Framework, and am running into a snag when casting Entity Framework object types to/from objects of a class derived from that object type.
To provide context, I am selecting Survey objects from my Entity Framework DB (records from a Surveys table), for which I have created a derived class that I will actually cast these entity objects to before using them in my application – such that the derived class’s signature looks something like:
public sealed class SurveyExtended : Survey
{
public SurveyExtended() : base()
{
// non-base class members initialized here
}
}
And when using LINQ to populate a collection of these objects, I am casting them to the SurveyExtended type using code similar to:
var listOfSurveyExtendedObjects = ( from record in contextFactory.SurveysDbContext.Surveys
select new SurveyExtended()
{
Name = record.Name,
Data = record.Data,
Date = record.Date
}
);
Please note, I know I could use lambda to do the same thing, but I’m just trying to illustrate a concept.
All is well and good, until I actually try and execute DML against SurveysDbContext to do things like UPDATE or DELETE the original record after processing it in my application, such as: contextFactory.SurveysDbContext.Surveys.DeleteObject( surveyExtendedObject );.
Of course this isn’t going to work, because I’m manipulating SurveyExtended objects, not the original Survey entity objects, and the ObjectStateManager will throw an InvalidOperationException because the object itself cannot be found. That is to be expected.
I guess what I’m looking for are suggestions and alternative approaches to this scenario. Should I attempt to cast back to Survey objects before trying to DbContext.DeleteObject( record );, or change my approach to this problem entirely? In similar situations, what methods did/do you use, and what benefits/drawbacks do they offer?
The options that come to mind are either cast it back before saving / interacting with EF, or switch to using something like a decorator pattern where the Extended object encapsulates the Survey. Though the second option either means you need to mimic the encapsulated object exposing pass-through accessors (double the code, double the fun) or change referencing code to access
SurveyExtended.Survey.Property.