{"record":{"id":"e68ec90584022bd9","repo":"dotnet/efcore","slug":"the-dbfunction-function-has-an-invalid-return-e68ec9","errorCode":null,"errorMessage":"The DbFunction '{function}' has an invalid return type '{type}'. Owned entity types cannot be used as the return type of a DbFunction.","messagePattern":"The DbFunction '(.+?)' has an invalid return type '(.+?)'\\. Owned entity types cannot be used as the return type of a DbFunction\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":382,"sourceCode":"        {\n            if (dbFunction.TypeMapping == null)\n            {\n                throw new InvalidOperationException(\n                    RelationalStrings.DbFunctionInvalidReturnType(\n                        dbFunction.ModelName,\n                        dbFunction.ReturnType.ShortDisplayName()));\n            }\n        }\n        else\n        {\n            var elementType = dbFunction.ReturnType.GetGenericArguments()[0];\n            var entityType = model.FindEntityType(elementType);\n\n            if (entityType?.IsOwned() == true\n                || ((IConventionModel)model).IsOwned(elementType)\n                || (entityType == null && model.GetEntityTypes().Any(e => e.ClrType == elementType)))\n            {\n                throw new InvalidOperationException(\n                    RelationalStrings.DbFunctionInvalidIQueryableOwnedReturnType(\n                        dbFunction.ModelName, elementType.ShortDisplayName()));\n            }\n\n            if (entityType == null)\n            {\n                throw new InvalidOperationException(\n                    RelationalStrings.DbFunctionInvalidReturnEntityType(\n                        dbFunction.ModelName, dbFunction.ReturnType.ShortDisplayName(), elementType.ShortDisplayName()));\n            }\n\n            if ((entityType.BaseType != null || entityType.GetDerivedTypes().Any())\n                && entityType.FindDiscriminatorProperty() == null)\n            {\n                throw new InvalidOperationException(\n                    RelationalStrings.TableValuedFunctionNonTph(dbFunction.ModelName, entityType.DisplayName()));\n            }\n        }","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L364-L400","documentation":"ValidateDbFunction (RelationalModelValidator.cs:378-385) throws for a non-scalar (IQueryable-returning) DbFunction whose element type is an owned entity type. Owned entity types are tied to an owner and cannot stand alone as the row type of a TVF/result set, so using one as a DbFunction's IQueryable<T> return is rejected.","triggerScenarios":"Declaring HasDbFunction returning IQueryable<OwnedEntity> where OwnedEntity is configured with OwnsOne/OwnsMany (owned). Thrown at model validation.","commonSituations":"Trying to expose a TVF whose row shape is an owned type; refactoring a query to a DbFunction without realizing the row type is owned; aggregating owned entities into a function result.","solutions":["Return a non-owned entity type from the DbFunction (define a standalone entity for the TVF row shape).","If you need the owned shape, project to a separate non-owned DTO/entity type registered in the model and map the TVF to that.","Remove the Owns* configuration if the type should be independent and usable as a TVF row."],"exampleFix":"// before\npublic IQueryable<Address> AddressesInCity(string city) => null!;\nmodelBuilder.Entity<User>().OwnsOne(u => u.Address);\nmodelBuilder.HasDbFunction(() => AddressesInCity(default)); // Address is owned -> throws\n\n// after - use a standalone (non-owned) entity for the TVF row\npublic IQueryable<AddressView> AddressesInCity(string city) => null!;\nmodelBuilder.Entity<AddressView>().HasNoKey();\nmodelBuilder.HasDbFunction(() => AddressesInCity(default));","handlingStrategy":"validation","validationCode":"foreach (var fn in context.Model.GetDbFunctions())\n{\n    if (!fn.IsScalar)\n    {\n        var elementType = fn.ReturnType.GetGenericArguments()[0];\n        var et = context.Model.FindEntityType(elementType);\n        if (et?.IsOwned() == true\n            || ((IConventionModel)context.Model).IsOwned(elementType))\n        {\n            // will throw - return a non-owned entity type from this DbFunction.\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never use an owned entity type as a DbFunction's IQueryable<T> element.","Define a standalone (often keyless) entity for TVF row shapes.","Review ownership when promoting a query to a DbFunction."],"tags":["dbfunction","owned-entity","tvf","model-validation"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}