I'm using OData in an ASP.NET Core Web API.
I have the following entities:
public class Equipment
{
[Key]
public long EquipmentId { get; set; }
[Required]
public string EquipmentCode { get; set; }
[Required]
public string EquipmentTitle { get; set; }
[Required]
public bool IsActive { get; set; }
public DateTime CreationDate { get; set; }
//Navigation properties
[ForeignKey("CostCenterRefNavigation")]
public int CostCenterRef { get; set; }
public CostCenter CostCenterRefNavigation { get; set; }
[ForeignKey("EquipmentCatalogueRefNavigation")]
public int? EquipmentCatalogueRef { get; set; }
public EquipmentCatalogue EquipmentCatalogueRefNavigation { get; set; }
[ForeignKey("EquipmentInfoRefNavigation")]
public int? EquipmentInfoRef { get; set; }
public EquipmentInfo EquipmentInfoRefNavigation { get; set; }
[ForeignKey("EquipmentCategoryRefNavigation")]
public int? EquipmentCategoryRef { get; set; }
public EquipmentCategory EquipmentCategoryRefNavigation { get; set; }
[ForeignKey("equipmentTypeRefNavigation")]
public int EquipmentTypeRef { get; set; }
public EquipmentType equipmentTypeRefNavigation { get; set; }
[ForeignKey("BOMRefNavigation")]
public long? BomRef { get; set; }
public BOM? BOMRefNavigation { get; set; }
[JsonIgnore]
public virtual List<ServiceEquipment> ServiceEquipmentRefNavigation { get; set; }
[JsonIgnore]
public virtual List<WorkOrder>? WorkOrdersRefNavigation { get; set; }
[JsonIgnore]
public virtual List<WorkOrderDocument>? WorkOrderDocumentsRefNavigation { get; set; }
[JsonIgnore]
public virtual List<EquipmentFailure> EquipmentFailuresRefNavigation { get; set; }
[JsonIgnore]
public virtual List<EquipmentFailureCause> EquipmentFailureCausesRefNavigation { get; set; }
[JsonIgnore]
public virtual List<FailureReport> FailureReportsEquipmentRefNavigation { get; set; }
}
public class EquipmentCategory
{
[Key]
public int EquipmentCategoryId { get; set; }
[Required]
public string CategoryCode { get; set; }
[Required]
public string CategoryName { get; set; }
//Navigation property
[JsonIgnore]
public virtual List<Equipment> EquipmentsRefNavigation { get; set; }
}
public class EquipmentCatalogue
{
[Key]
public int EquipmentCatalogueId { get; set; }
[Required]
public string RefFileName { get; set; }
//Navigation property
[JsonIgnore]
public virtual List<Equipment>? EquipmentsRefNavigation { get; set; }
}
public class EquipmentInfo
{
[Key]
public int EquipmentInfoId { get; set; }
[Required]
public string RefFileName { get; set; }
//Navigation Property
[JsonIgnore]
public virtual List<Equipment>? EquipmentsRefNavigation { get; set; }
}
public class EquipmentType
{
[Key]
public int EquipmentTypeId { get; set; }
[Required]
public string EquipmentTypeTitle { get; set; }
//Navigation property
[JsonIgnore]
public virtual List<Equipment>? EquipmentsRefNavigation { get; set; }
}
This is my program.cs
file:
static IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new();
.
.
builder.EntitySet<Equipment>("Equipments");
.
.
return builder.GetEdmModel();
}
.
.
builder.Services.AddControllers().AddOData(opt => opt.AddRouteComponents("odata", GetEdmModel()).Select().Filter().OrderBy().Count().Expand().SetMaxTop(null));
When I call the target endpoint using the http://localhost:5000/odata/Equipments
query, I get an exception:
Microsoft.OData.ODataException: The property 'EquipmentCatalogueRef[Nullable=False]' of type 'Edm.Int32' has a null value, which is not allowed.
How can I fix this error?
Update #1:
OData controller for Equipment entity:
[HttpGet]
[EnableQuery]
[Authorize(Roles = "System,Administrator")]
public IQueryable<Equipment> Get()
{
IQueryable<Equipment> eqList = _sqlServerContext.Equipments.AsQueryable();
return eqList;
}
Update #2: I have provided a simple project here. You can see the problem by url query http://localhost:5147/odata/user?$expand=FileRefNavigation
.
One thing you should try is to make the key property and navigation one consistent i.e. either both nullable or both non-nullable:
[ForeignKey("EquipmentCatalogueRefNavigation")]
public int? EquipmentCatalogueRef { get; set; }
public EquipmentCatalogue? EquipmentCatalogueRefNavigation { get; set; }