0

I'm trying to get a repository pattern working with MVC2 and EF. My problem is within the concrete repository. When I attempt to cast the EF query results as an IEnumerable collection of view-model entities:

Unable to cast object of type     
'System.Data.Objects.ObjectQuery`1[Data_Service.MediaReleases]' 
to type 
    'System.Collections.Generic.IEnumerable`1[TestMVCWithFacory.Models.Entities.MediaReleaseModel]'.

I sense that's a bone-headed thing to try to do -- and it's something with Linq, and how deferred execution works, but I don't really understand the voodoo.

So what is it that I'm mis-understanding there, and how do I address it?

The view-model:

public class MediaReleaseModel
{
    public string Headline { get; set; }
    public string FullText { get; set; }
}

The repository interface:

public interface IMediaReleasesRepository
{
    IEnumerable<MediaReleaseModel> MediaReleases { get;}
}

The concrete repository:

public class MediaReleaseRepository : IMediaReleasesRepository
{
    private NewsEntities DataContext = new NewsEntities();
    private IEnumerable<MediaReleases> _MRs;

    public MediaReleaseRepository()
    {
        _MRs = from art in DataContext.MediaReleases select art;
    }

    public IEnumerable<MediaReleaseModel> MediaReleases
    {
        get { return (IEnumerable<MediaReleaseModel>)_MRs; }
    }

}

Controller:

public class HomeController : Controller
{
    private IMediaReleasesRepository _MRRepository;
    public HomeController()
    {
        _MRRepository= new MediaReleaseRepository();
    }

    public ViewResult index()
    {
        return View(_MRRepository.MediaReleases.ToList());
    }

}

1 Answer 1

2

You're trying to cast collection of MediaReleases to collection of MediaReleaseModels. If MediaReleaseModel is a separate class, this can't be done just by casting. Generally, cast will succeed only in one inheritance chain or when conversion operators are defined, which is not the case here.

What you need here is rewriting the MediaRelease fields to you model object (it can be automated using tools like AutoMapper), i.e. with help of LINQ:

public IEnumerable<MediaReleaseModel> MediaReleases
{
    get
    {
        return _MRs.Select(x => new MediaReleaseModel() 
        {
            Prop1 = x.Prop1 
            /* etc. */
        });
    }
}

One suggestion at the side: it's better not to have logic like that in constructor, creating objects should be cheap operation and it's a bit strange when the data are fetched before they are really needed.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. Re: your last line: you're referring to the linq statement in MediaReleaseRepository, correct? (not calling the repository in the controller constructor?)
Yes. Generally, constructors should only collect dependencies and avoid doing "real work". Your query can be easily moved to MediaReleases property.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.