views:

84

answers:

3

Let's say we have an ASP.NET MVC View like this:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<dynamic>" %>
<%: Html.EditorFor(model => model.ServiceDate) %>
<%: Html.ValidationMessageFor(model => model.ServiceDate, "*")%>

and we have Model classes that are similar but not exactly the same, for instance Invoice and Quote, which both contain the ServiceDate property. Those two classes do not inherit from the same base class, actually they have no base class currently.

  1. How can I get them to inherit from the same base class when those two are generated by EF? If I would be able to do that, I could replace the dynamic and specify the base class as the View's strong type.

  2. I was under impression that this was the case that dynamic was built for. But obviously it does not work because there's an exception that's apparently coming from LINQ to EF:

    CS1963: An expression tree may not contain a dynamic operation

Although it does say in the VS 2010 editor that expression will be resolved at runtime, it is not, but fails in error.

A: 

It seems that you are trying to use classes generated by EF in your views. I would recommend you not doing this. That's what ViewModels are supposed to do. Don't be afraid to create a view model for each view (even if you had to repeat some properties) and avoid passing the Model. Also having views that are strongly typed to <dynamic> is as if you had weakly typed views. Once again: avoid them:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<SomeAdaptedViewModel>" %>
<%: Html.EditorFor(model => model.ServiceDate) %>
<%: Html.ValidationMessageFor(model => model.ServiceDate, "*")%>
Darin Dimitrov
I've been over this time and time again and in some cases I would create custom Model classes. But in this case there is no need for that, everything is fine, I get along nicely using partial classes to extend those EF ones or to add validation annotation, so all in all it works great, it's simple to maintain and I won't change it. I'm aware of the implications it brings and best practices, which are to be followed (but not blindly).
mare
@mare, there's always a need to use view models, believe me it will make your life much easier.
Darin Dimitrov
A: 

First of all, which EF version are you using? I suppose your using EFv1, right? You can add inheritance to your models that come from EF. They are all defined as parcial classes by the framework. That means you can create another class with the same name (also parcial) that inherits from the base class.

By the way, I recommend you to use ViewModels in that case. Avoid using inheritance just to reuse some properties, inheritance should be used to add polymorphic behaviour to your classes.

Guilherme Oenning
Downvoted because extending with partial classes does not allow to change the base class in C# - Partial declarations must not specify different base class. And I'm using EFv4 with .NET 4 and ASP.NET MVC 2.
mare
True. But you can create an interface with ServiceDate property and in your partial declarations implement this interface. Doing so, you can specify the interface as the View's strong type. Right? Or am I wrong again? I'm not with VS here right now.
Guilherme Oenning
this does work..
mare
+1  A: 

1) Classes generated by Entity Framework use the partial keyword. This means you can easily extend them and not worry about code generation wiping out your changes.

So lets say EF generates: public partial class Customer

What you can do is define another .cs file called Customer_Partial.cs ( just my personal naming preference ) and then do something like:

 public partial class Customer : IMySharedInterface
 {  
 }

Then your view pages use:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IMySharedInterface>" %>

and then access your model properties in a strongly typed way.

2) I think this is caused by you passing an IQueryable into your view. Not sure though. With the above solution you won't have to worry about it.

jfar
@jfar thanks but you actually repeated everything @Guilherme said.
mare
@mare, Sure, I repeated it except for the code examples, interfaces instead of base classes, attempt at answering #2 and didn't slap you on the wrist for using EF classes in your views. ;)
jfar
upvoting but accepting Guilherme's answer coz he needs points ;)
mare
@mare I'm glad I put in the extra effort to improve upon his answer.
jfar