{"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/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L364-L400","documentation":"ValidateDbFunction throws DbFunctionInvalidIQueryableOwnedReturnType when a non-scalar DbFunction (returns IQueryable<T>) has T as an owned entity type, or a type marked IsOwned, or a type shared as owned across entity types. DbFunctions returning queryables cannot return owned entities because ownership ties the entity to a specific owner, not to a free-standing function result.","triggerScenarios":"Defining HasDbFunction on a method returning IQueryable<OwnedEntity> where OwnedEntity is configured via OwnsOne/OwnsMany or marked [Owned]. The validator checks `entityType?.IsOwned() == true || model.IsOwned(elementType) || (entityType == null && some entity shares the CLR type)`.","commonSituations":"Reusing an owned entity type as the element of a TVF/queryable DbFunction; migrating from regular entity to owned and forgetting to update the DbFunction; scaffolding table-valued functions whose row type was later marked owned.","solutions":["Use a non-owned entity type as the IQueryable<T> element of the DbFunction.","Define a dedicated read-model entity type (not owned) that mirrors the TVF columns and map the DbFunction to it.","If the data must stay owned elsewhere, project the DbFunction into a DTO via FromSqlRaw and a SqlQueryRaw<T> instead."],"exampleFix":"// before — Owner is an owned entity\n[Owned] public class AddressRow { public string City { get; set; } }\npublic IQueryable<AddressRow> ActiveAddresses(this DbContext db)\n    => throw new NotImplementedException();\nmodelBuilder.HasDbFunction(...); // throws\n\n// after — dedicated non-owned read model\npublic class AddressView { public string City { get; set; } }\nmodelBuilder.Entity<AddressView>().HasNoKey();\npublic IQueryable<AddressView> ActiveAddresses(this DbContext db)\n    => throw new NotImplementedException();","handlingStrategy":"validation","validationCode":"var elementType = dbFunction.ReturnType.GetGenericArguments()[0];\nvar et = dbFunction.Model.FindEntityType(elementType);\nif (et?.IsOwned() == true || ((IConventionModel)dbFunction.Model).IsOwned(elementType))\n    throw new InvalidOperationException($\"DbFunction cannot return owned entity {elementType}.\");","typeGuard":"static bool ReturnsOwnedEntity(IDbFunction f)\n{\n    var t = f.ReturnType.GetGenericArguments()[0];\n    var e = f.Model.FindEntityType(t);\n    return e?.IsOwned() == true || ((IConventionModel)f.Model).IsOwned(t);\n}","tryCatchPattern":null,"preventionTips":["Never use an owned entity type as the IQueryable<T> element of a DbFunction.","Define a dedicated keyless read-model entity for TVF results.","Audit DbFunctions when converting entities to owned to catch invalid returns."],"tags":["dbfunction","owned-types","queryable","tvf","model-validation"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}