1

I am using EntityFramework code first. Lets say this is my classes:

public abstract class BlockModel
{
    public int Id { get; set; }
}

public class ModuleBlockModel : BlockModel
{

}

public abstract class BlockModelParameter
{
   public int Id { get; set; }
   public virtual BlockModel BlockModel { get; set; }
}

public class ModuleBlockModelParameter : BlockModelParameter
{
   public new virtual ModuleBlockModel BlockModel { get; set; }
}

and my DbContext class:

public IDbSet<ModuleBlockModel> BlockModels { get; set; }
public IDbSet<ModuleBlockModelParameter> BlockModelParameters { get; set;}

when i try to get items, EF creating another property same name. One is null and other is correct.

Sample

and try to get BlockModel value throws null value.

Is there an EF bug? How can get BlockModel property correctly.

Thanks.

Şafak
  • 87
  • 2
  • 2
  • 6
  • What is your question? Please remember to clearly state what your desired outcome is, or what you're unclear about if you simply want an explanation of behavior. – Michael L. Mar 20 '17 at 19:25
  • Edited question – Şafak Mar 20 '17 at 19:35
  • Show your fetch command. Do you have an Include() in your LINQ? `var myBlockModelParmWithBlockModel = context.BlockModelParameters.Include(bmp => bmp.BlockModel).FirstOrDefault();` – Steve Greene Mar 20 '17 at 20:00
  • @SteveGreene yes. var blockModelParameters = Db.BlockModelParameters.Include(x => x.BlockModel).ToList(); – Şafak Mar 20 '17 at 20:37

1 Answers1

1

The problem is that you can't 'hide' the property virtual BlockModel BlockModel with the property new virtual ModuleBlockModel BlockModel because it is technically a different type signature, even though one is a sub-type of the other.

You can try resolving this with generics (they allow the 'type' to be set dynamically), like this:

public abstract class BlockModel
{
    public int Id { get; set; }
}

public class ModuleBlockModel : BlockModel
{

}

public abstract class BlockModelParameter<TBlockModel>
    // Guarantee that TBlockModel is sub-type of BlockModel
    where TBlockModel : BlockModel
{
    public int Id { get; set; }

    // Type of BlockModel will be whatever type is specified for TBlockModel
    public virtual TBlockModel BlockModel { get; set; }
}

// Specify ModuleBlockModel as the generic type argument for BlockModelParameter
// Note: A subtype of a generic class doesn't also have to be generic
public class ModuleBlockModelParameter 
    : BlockModelParameter<ModuleBlockModel>
{
    // Now you can 'hide' the parent's BlockModel property, since the 
    // signatures match - or, better yet, you can omit it entirely, 
    // unless you need a type-specific implementation
    public new virtual ModuleBlockModel BlockModel { get; set; }
}
Michael L.
  • 620
  • 3
  • 17
  • 2
    But now you don't need `public new virtual ModuleBlockModel` – Gert Arnold Mar 20 '17 at 21:00
  • @GertArnold Quite right, unless he has a type-specific implementation (which he doesn't, in his example) – Michael L. Mar 20 '17 at 21:13
  • @MichaelL. thanks for reply. Gives error at runtime. "BlockModelParameter`1[BlockModel] was not mapped. . Check that the type has not been explicitly excluded by using the Ignore method or NotMappedAttribute data annotation. Verify that the type was defined as a class, is not primitive or generic, and does not inherit from EntityObject.'" – Şafak Mar 20 '17 at 22:44