is there any way to use interfaces as navigation properties in EF6? I've found related topics for EF4 or earlier where it didn't seem to be possible; generally, inheritance seems to have improved a lot since then, but I haven't found a way to make this specific problem work yet.
Example:
public interface IPerson
{
string name { get; set; }
}
public class Man : IPerson { /* ... */ }
public class Woman : IPerson { /* ... */ }
public interface ICar
{
IPerson driver { get; set; }
}
public class Car : ICar
{
public virtual IPerson driver { get; set; } // This won't map
}
Is this possible in any way? If not, what'd be an advisable way to do this?
Because currently I don't see any way for an interface to have a set-able property whose type is some other interface (the IPerson property of ICar, for example), which kind of strikes me as a very serious design limitation?!
Okay, for those possibly facing the same issue in the future. After more testing around, this is how I'm doing it now.
public interface IPerson
{
string name { get; set; }
}
public abstract class APerson : IPerson
{
public string name { get; set; }
}
public class Man : APerson { /* ... */ }
public class Woman : APerson { /* ... */ }
public interface ICar
{
IPerson driver { get; set; }
}
public class Car : ICar
{
// This maps to the database
public virtual APerson driver { get; set; }
// And this implements the interface
ICar.driver
{
get
{
return (IPerson)driver;
}
set
{
if(!(value is APerson))
throw new InvalidCastException("driver must inherit from APerson");
driver = (APerson)value;
}
}
}
This gets a bit more tricky when having one-to-many / many-to-many relations, for that case I've written a class that inherits from Collection<Interface type>, but also implements ICollection<Abstract base type>, and again throws an exception when someone tries adding/setting any object that doesn't inherit from the abstract base class. It's basically a Collection<IPerson> that's guaranteed to only contain objects inheriting that inherit APerson, if you will.
This solution is definitely not ideal, because it just throws an exception if somebody tries assigning a value to driver that does not inherit from APerson, so no compile-time safety here. But it's the best solution I could think of so far, if you really want to keep your interfaces separate and self-contained.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With