2

This post (https://stackoverflow.com/a/14486260/894358) suggests that Breeze does support inheritance, but my breeze manager is not able to understand the metadata being returned from the API. The server will return metadata and JSON results from other action methods, but when the manager tries to interpret the metadata it throws the error: "Cannot read propertyRef of undefined".

Here is my very simple implementation (Code First Migrations generates the database):

namespace VerySimpleVehicleModel.Models
{    
    public abstract class Vehicle
    {
        public int Id { get; set; }
        public int Speed { get; set; }
    }

    public class Bus: Vehicle
    {
        public int Capacity { get; set; }
    }

    public class Car : Vehicle
    {
        public string Color { get; set; }
    }

    public class VehicleContext : DbContext
    {
        public DbSet<Car> Cars { get; set; }
        public DbSet<Bus> Buses { get; set; }
        public DbSet<Vehicle> Vehicles { get; set; }
    }
}

namespace VerySimpleVehicleModel.Controllers
{
    [BreezeController]
    public class BreezeController : ApiController
    {
        readonly EFContextProvider<VehicleContext> _contextProvider = new EFContextProvider<VehicleContext>();
        [HttpGet]
        public string Metadata()
        {
            return _contextProvider.Metadata();
        }
        [HttpGet]
        public IQueryable<Car> Cars()
        {
            return _contextProvider.Context.Cars;

        }
    }
}   

And here is the metadata returned from the Metadata action method:

"{
    \"schema\":
    {
        \"namespace\":\"VerySimpleVehicleModel.Models\",
        \"alias\":\"Self\",
        \"d4p1:UseStrongSpatialTypes\":\"false\",
        \"xmlns:d4p1\":\"http://schemas.microsoft.com/ado/2009/02/edm/annotation\",
        \"xmlns\":\"http://schemas.microsoft.com/ado/2009/11/edm\",
        \"cSpaceOSpaceMapping\":\"
    [
        [
            \\\"VerySimpleVehicleModel.Models.Vehicle\\\",
            \\\"VerySimpleVehicleModel.Models.Vehicle\\\"
        ],
        [
            \\\"VerySimpleVehicleModel.Models.Car\\\",
            \\\"VerySimpleVehicleModel.Models.Car\\\"
        ],
        [
            \\\"VerySimpleVehicleModel.Models.Bus\\\",
            \\\"VerySimpleVehicleModel.Models.Bus\\\"
        ]
    ]
    \",\"entityType\":
        [
            {
                \"name\":\"Car\",
                \"baseType\":\"Self.Vehicle\",
                \"property\":
                {
                    \"name\":\"Color\",
                    \"type\":\"Edm.String\",
                    \"fixedLength\":\"false\",\"maxLength\":\"Max\",
                    \"unicode\":\"true\",\"nullable\":\"true\"
                }
            },
            {
                \"name\":\"Bus\",
                \"baseType\":\"Self.Vehicle\",
                \"property\":{\"name\":\"Capacity\",
                \"type\":\"Edm.Int32\",\"nullable\":\"false\"}
            },
            {
                \"name\":\"Vehicle\",
                \"abstract\":\"true\",
                \"key\":{\"propertyRef\":{\"name\":\"Id\"}},
                \"property\":
                [
                    {\"name\":\"Id\",\"type\":\"Edm.Int32\",\"nullable\":\"false\",\"d4p1:StoreGeneratedPattern\":\"Identity\"},
                    {\"name\":\"Speed\",\"type\":\"Edm.Int32\",\"nullable\":\"false\"}
                ]
            }
        ]
        ,\"entityContainer\":
        {
            \"name\":\"VehicleContext\",
            \"entitySet\":
            {
                \"name\":\"Vehicles\",
                \"entityType\":\"Self.Vehicle\"
            }
        }
    }
}"
Community
  • 1
  • 1
dave walker
  • 3,058
  • 1
  • 24
  • 30

1 Answers1

2

I can't reproduce a problem with your example. In fact, it works like a charm.

I copied it almost verbatim to the DocCode sample because it is so simple and we needed a simple one before getting into the complexities of the BillingDetails example (will publish next release).

This is a standard TPH model with an abstract base class. The key is recognized in metadata; look at the Vehicle base class for this line:

\"key\":{\"propertyRef\":{\"name\":\"Id\"}},

What is odd is that you are receiving metadata in the old string format. When I look at the payload for the metadata in my test runs I get a JSON object:

{"schema":{"namespace":"Inher ...
  "entityType":[{"name":"Vehicle",
     "abstract":"true",
     "key":{"propertyRef":{"name":"Id"}}, ...
}]}]}}}

I suspect that you have an old copy of the Breeze.WebApi.dll. Perhaps you updated the Breeze NuGet package and the old assembly got trapped in the references or an old script file was retained. Try uninstalling and re-installing Breeze. Look carefully at the NuGet console log to make sure everything was replaced.

Ward
  • 17,793
  • 4
  • 37
  • 53
  • You're right. When I updated from the Nuget command line everything started working again. – Ali B May 20 '13 at 21:17
  • Yes, it works. Can't believe I didn't try that before the other 50 things I tried. – dave walker May 20 '13 at 23:24
  • Ward, does it support table per type? – dave walker May 20 '13 at 23:28
  • Yes. TPT as well as TPH and TPC. You'll find examples of each in DocCode, the *inheritanceTests.js* and its supporting InheritanceModels. I always worry about the performance of any inheritance model other than TPH but, as they say, it's your funeral. – Ward May 21 '13 at 00:38
  • Thanks Ward, I just got a TPT model working. Can you point me to any sources that discuss the performance trade-offs between TPT and TPH. Is performance lost at command, query or both? – dave walker May 21 '13 at 01:02
  • TPH is simple because it's all in one table. It's a downer if you have a lot of sub-types each with their own columns because you get nulls. It's close to fatal if any sub-type column is not nullable. But usually the sub-types have few special columns, all nullable. The concern with TPT is that you have a separate table for every sub-type. That's a guaranteed join. If you have a lot of sub-types and do a polymorphic query on the base type, you get unions to go with those joins. You can search the net for more depth. – Ward May 21 '13 at 05:48