Repository: microsoft/kiota (csharp)

Issue:
Problem generating model(s) when schema has type: object with oneOf with single ref referring to component using allOf
### What are you generating using Kiota, clients or plugins?

API Client/SDK

### In what context or format are you using Kiota?

Nuget tool

### Client library/SDK language

Csharp

### Describe the bug

This is similar issue as #5808 where the contract we received has `oneOf` hierarchies where there is only a single ref under `oneOf` but the schema had type: object set. If the type: object is set, the contract does not generate the expected models.

### Expected behavior

Kiota generates code for both schemas, with or without `type: object`.

```yaml
    # ... rest of the schema ...
    # Does not work (Component1) is not generated at all or mentioned in the
    # generated ExampleWithSingleOneOfWithTypeObject type.
    ExampleWithSingleOneOfWithTypeObject:
      # Removing this works
      type: object
      oneOf:
        - $ref: "#/components/schemas/Component1"
      discriminator:
        propertyName: objectType

    # Does work (Component2) e.g. Component2 is used in place of ExampleWithSingleOneOfWithoutTypeObject
    ExampleWithSingleOneOfWithoutTypeObject:
      oneOf:
        - $ref: "#/components/schemas/Component2"
      discriminator:
        propertyName: objectType
    # ... rest of the schema ...
```

### How to reproduce

I have a repository with the generated client and example schema which reproduce the issue available:

- Schema: [https://github.com/vipentti/kiota-type-object-one-of-issue/blob/main/DiscriminatorProblemSampleHierarchy.yaml](https://github.com/vipentti/kiota-type-object-one-of-issue/blob/main/DiscriminatorProblemSampleHierarchy.yaml)
- Generated code [https://github.com/vipentti/kiota-type-object-one-of-issue/tree/main/Generated/Hierarchy/CSharp](https://github.com/vipentti/kiota-type-object-one-of-issue/tree/main/Generated/Hierarchy/CSharp)

### Open API description file

https://github.com/vipentti/kiota-type-object-one-of-issue/blob/main/DiscriminatorProblemSampleHierarchy.yaml

### Kiota Version

1.21.0+ec3a3fff9fc6e2fb7de190d37969fa2e93aefdf5

### Latest Kiota version known to work for scenario above?(Not required)

_No response_

### Known Workarounds

_No response_

### Configuration

- OS: Windows 11
- Architecture: x64

### Debug output

<details><summary>Click to expand log</summary>

```
info: Kiota.Builder.KiotaBuilder[0]
      Cleaning output directory _root_\kiota-type-object-one-of-issue\.\Generated\Hierarchy\CSharp
dbug: Kiota.Builder.KiotaBuilder[0]
      kiota version 1.21.0
info: Kiota.Builder.KiotaBuilder[0]
      loaded description from local source
dbug: Kiota.Builder.KiotaBuilder[0]
      step 1 - reading the stream - took 00:00:00.0052293
dbug: Kiota.Builder.KiotaBuilder[0]
      step 2 - parsing the document - took 00:00:00.0687352
dbug: Kiota.Builder.KiotaBuilder[0]
      step 3 - updating generation configuration from kiota extension - took 00:00:00.0000606
dbug: Kiota.Builder.KiotaBuilder[0]
      step 4 - filtering API paths with patterns - took 00:00:00.0032164
info: Kiota.Builder.KiotaBuilder[0]
      Client root URL set to https://mytodos.doesnotexist
dbug: Kiota.Builder.KiotaBuilder[0]
      step 5 - checking whether the output should be updated - took 00:00:00.0077425
dbug: Kiota.Builder.KiotaBuilder[0]
      step 6 - create uri space - took 00:00:00.0023395
dbug: Kiota.Builder.KiotaBuilder[0]
      InitializeInheritanceIndex 00:00:00.0023997
dbug: Kiota.Builder.KiotaBuilder[0]
      CreateRequestBuilderClass 00:00:00
dbug: Kiota.Builder.KiotaBuilder[0]
      MapTypeDefinitions 00:00:00.0034072
info: Kiota.Builder.KiotaBuilder[0]
      Removing unused model Component1 as it is not referenced by the client API surface
dbug: Kiota.Builder.KiotaBuilder[0]
      TrimInheritedModels 00:00:00
dbug: Kiota.Builder.KiotaBuilder[0]
      CleanUpInternalState 00:00:00
dbug: Kiota.Builder.KiotaBuilder[0]
      step 7 - create source model - took 00:00:00.0470989
dbug: Kiota.Builder.KiotaBuilder[0]
      14ms: Language refinement applied
dbug: Kiota.Builder.KiotaBuilder[0]
      step 8 - refine by language - took 00:00:00.0149214
dbug: Kiota.Builder.KiotaBuilder[0]
      step 9 - writing files - took 00:00:00.0197369
info: Kiota.Builder.KiotaBuilder[0]
      loaded description from local source
dbug: Kiota.Builder.KiotaBuilder[0]
      step 10 - writing lock file - took 00:00:00.0085050
Generation completed successfully
Client base url set to https://mytodos.doesnotexist
dbug: Kiota.Builder.KiotaBuilder[0]
      Api manifest path: _root_\kiota-type-object-one-of-issue\apimanifest.json

Hint: use the info command to get the list of dependencies you need to add to your project.
Example: kiota info -d "_root_\kiota-type-object-one-of-issue\.\DiscriminatorProblemSampleHierarchy.yaml" -l CSharp

Hint: use the --include-path and --exclude-path options with glob patterns to filter the paths generated.
Example: kiota generate --include-path "**/foo" -d "_root_\kiota-type-object-one-of-issue\.\DiscriminatorProblemSampleHierarchy.yaml"
```
</details>


### Other information

Continuation of issue #5808 which was fixed by #5827.

Pull request description:
This adds these scenarios as specific cases in `KiotaBuilder.CreateModelDeclarations`. Not sure if this is the best place to handle this but at least this fixes the issue where the properties & possible inheritance were completely missing while not breaking anything existing.

Fixes #5921

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 68607e75e9..1a4befd77e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 - Fixed a bug in generation when a referenced schema in an allOf was a primitive [#5701](https://github.com/microsoft/kiota/issues/5701).
 - Fixed a bug where inherited error models would be missing interface declarations. [#5888](https://github.com/microsoft/kiota/issues/5888)
+- Fixed a bug where oneOf/anyOf schemas with single references to inheritance or intersections would be missing properties. [#5921](https://github.com/microsoft/kiota/issues/5921)
 
 ## [1.21.0] - 2024-12-05
 
diff --git a/src/Kiota.Builder/Extensions/IListExtensions.cs b/src/Kiota.Builder/Extensions/IListExtensions.cs
new file mode 100644
index 0000000000..ec2aed7711
--- /dev/null
+++ b/src/Kiota.Builder/Extensions/IListExtensions.cs
@@ -0,0 +1,29 @@
+﻿using System.Collections.Generic;
+
+namespace Kiota.Builder.Extensions;
+
+public static class IListExtensions
+{
+    /// <summary>
+    /// Returns the only element of this list when it has count of exactly <c>1</c>
+    /// </summary>
+    /// <typeparam name="T">The contained item type.</typeparam>
+    /// <param name="items">The items.</param>
+    /// <returns>The only element or null.</returns>
+    internal static T? OnlyOneOrDefault<T>(this IList<T> items) =>
+        items.Count == 1 ? items[0] : default;
+
+    /// <summary>
+    /// Adds the provided <paramref name="values"/> to this list.
+    /// </summary>
+    /// <typeparam name="T">The contained item type.</typeparam>
+    /// <param name="items">The items.</param>
+    /// <param name="values">The values to add.</param>
+    internal static void AddRange<T>(this IList<T> items, IEnumerable<T> values)
+    {
+        foreach (var item in values)
+        {
+            items.Add(item);
+        }
+    }
+}
diff --git a/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs b/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs
index cec1a3cf2b..ec9d9d2f6a 100644
--- a/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs
+++ b/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs
@@ -98,13 +98,7 @@ public static bool IsInherited(this OpenApiSchema? schema)
         if (schema is null || !schema.IsInclusiveUnion(0)) return null;
         var result = new OpenApiSchema(schema);
         result.AnyOf.Clear();
-        foreach (var subSchema in schema.AnyOf)
-        {
-            foreach (var property in subSchema.Properties)
-            {
-                result.Properties.TryAdd(property.Key, property.Value);
-            }
-        }
+        result.TryAddProperties(schema.AnyOf.SelectMany(static x => x.Properties));
         return result;
     }
 
@@ -113,14 +107,42 @@ public static bool IsInherited(this OpenApiSchema? schema)
         if (schema is null || !schema.IsExclusiveUnion(0)) return null;
         var result = new OpenApiSchema(schema);
         result.OneOf.Clear();
-        foreach (var subSchema in schema.OneOf)
+        result.TryAddProperties(schema.OneOf.SelectMany(static x => x.Properties));
+        return result;
+    }
+
+    internal static OpenApiSchema? MergeSingleInclusiveUnionInheritanceOrIntersectionSchemaEntries(this OpenApiSchema? schema)
+    {
+        if (schema is not null
+            && schema.IsInclusiveUnion(0)
+            && schema.AnyOf.OnlyOneOrDefault() is OpenApiSchema subSchema
+            && (subSchema.IsInherited() || subSchema.IsIntersection()))
         {
-            foreach (var property in subSchema.Properties)
-            {
-                result.Properties.TryAdd(property.Key, property.Value);
-            }
+            var result = new OpenApiSchema(schema);
+            result.AnyOf.Clear();
+            result.TryAddProperties(subSchema.Properties);
+            result.AllOf.AddRange(subSchema.AllOf);
+            return result;
         }
-        return result;
+
+        return null;
+    }
+
+    internal static OpenApiSchema? MergeSingleExclusiveUnionInheritanceOrIntersectionSchemaEntries(this OpenApiSchema? schema)
+    {
+        if (schema is not null
+            && schema.IsExclusiveUnion(0)
+            && schema.OneOf.OnlyOneOrDefault() is OpenApiSchema subSchema
+            && (subSchema.IsInherited() || subSchema.IsIntersection()))
+        {
+            var result = new OpenApiSchema(schema);
+            result.OneOf.Clear();
+            result.TryAddProperties(subSchema.Properties);
+            result.AllOf.AddRange(subSchema.AllOf);
+            return result;
+        }
+
+        return null;
     }
 
     internal static OpenApiSchema? MergeIntersectionSchemaEntries(this OpenApiSchema? schema, HashSet<OpenApiSchema>? schemasToExclude = default, bool overrideIntersection = false, Func<OpenApiSchema, bool>? filter = default)
@@ -144,11 +166,17 @@ public static bool IsInherited(this OpenApiSchema? schema)
             else if (discriminator.Mapping?.Any() ?? false)
                 result.Discriminator.Mapping = discriminator.Mapping.ToDictionary(static x => x.Key, static x => x.Value);
 
-        foreach (var propertyToMerge in entriesToMerge.SelectMany(static x => x.Properties))
+        result.TryAddProperties(entriesToMerge.SelectMany(static x => x.Properties));
+
+        return result;
+    }
+
+    internal static void TryAddProperties(this OpenApiSchema schema, IEnumerable<KeyValuePair<string, OpenApiSchema>> properties)
+    {
+        foreach (var property in properties)
         {
-            result.Properties.TryAdd(propertyToMerge.Key, propertyToMerge.Value);
+            schema.Properties.TryAdd(property.Key, property.Value);
         }
-        return result;
     }
 
     public static bool IsIntersection(this OpenApiSchema? schema)
diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs
index b4466a5bf0..450e392103 100644
--- a/src/Kiota.Builder/KiotaBuilder.cs
+++ b/src/Kiota.Builder/KiotaBuilder.cs
@@ -958,7 +958,7 @@ x.Parent is CodeIndexer ||
             var parentNS = x.Parent?.Parent?.Parent as CodeNamespace;
             CodeClass[] exceptions = x.Parent?.Parent is CodeClass parentClass ? [parentClass] : [];
             x.TypeDefinition = parentNS?.FindChildrenByName<CodeClass>(x.Name)
-                .Except(exceptions)// the property method should not reference itself as a return type. 
+                .Except(exceptions)// the property method should not reference itself as a return type.
                 .MinBy(shortestNamespaceOrder);
             // searching down first because most request builder properties on a request builder are just sub paths on the API
             if (x.TypeDefinition == null)
@@ -1833,6 +1833,18 @@ private CodeTypeBase CreateModelDeclarations(OpenApiUrlTreeNode currentNode, Ope
             return CreateComposedModelDeclaration(currentNode, schema, operation, suffix, codeNamespace, isRequestBody, typeNameForInlineSchema);
         }
 
+        // type: object with single oneOf referring to inheritance or intersection
+        if (schema.IsObjectType() && schema.MergeSingleExclusiveUnionInheritanceOrIntersectionSchemaEntries() is OpenApiSchema mergedExclusiveUnionSchema)
+        {
+            return CreateModelDeclarations(currentNode, mergedExclusiveUnionSchema, operation, parentElement, suffixForInlineSchema, response, typeNameForInlineSchema, isRequestBody);
+        }
+
+        // type: object with single anyOf referring to inheritance or intersection
+        if (schema.IsObjectType() && schema.MergeSingleInclusiveUnionInheritanceOrIntersectionSchemaEntries() is OpenApiSchema mergedInclusiveUnionSchema)
+        {
+            return CreateModelDeclarations(currentNode, mergedInclusiveUnionSchema, operation, parentElement, suffixForInlineSchema, response, typeNameForInlineSchema, isRequestBody);
+        }
+
         if (schema.IsObjectType() || schema.HasAnyProperty() || schema.IsEnum() || !string.IsNullOrEmpty(schema.AdditionalProperties?.Type))
         {
             // no inheritance or union type, often empty definitions with only additional properties are used as property bags.
@@ -1840,7 +1852,7 @@ private CodeTypeBase CreateModelDeclarations(OpenApiUrlTreeNode currentNode, Ope
         }
 
         if (schema.IsArray() &&
-            !schema.Items.IsArray()) // Only handle collections of primitives and complex types. Otherwise, multi-dimensional arrays would be recursively unwrapped undesirably to lead to incorrect serialization types. 
+            !schema.Items.IsArray()) // Only handle collections of primitives and complex types. Otherwise, multi-dimensional arrays would be recursively unwrapped undesirably to lead to incorrect serialization types.
         {
             // collections at root
             return CreateCollectionModelDeclaration(currentNode, schema, operation, codeNamespace, typeNameForInlineSchema, isRequestBody);
@@ -2230,7 +2242,7 @@ internal static void AddDiscriminatorMethod(CodeClass newClass, string discrimin
             logger.LogWarning("Discriminator {ComponentKey} not found in the OpenAPI document.", componentKey);
             return null;
         }
-        // Call CreateModelDeclarations with isViaDiscriminator=true. This is for a special case where we always generate a base class when types are referenced via a oneOf discriminator. 
+        // Call CreateModelDeclarations with isViaDiscriminator=true. This is for a special case where we always generate a base class when types are referenced via a oneOf discriminator.
         if (CreateModelDeclarations(currentNode, discriminatorSchema, currentOperation, GetShortestNamespace(currentNamespace, discriminatorSchema), string.Empty, null, string.Empty, false, true) is not CodeType result)
         {
             logger.LogWarning("Discriminator {ComponentKey} is not a valid model and points to a union type.", componentKey);
@@ -2238,7 +2250,7 @@ internal static void AddDiscriminatorMethod(CodeClass newClass, string discrimin
         }
         if (baseClass is not null && (result.TypeDefinition is not CodeClass codeClass || codeClass.StartBlock.Inherits is null))
         {
-            if (!baseClass.Equals(result.TypeDefinition))// don't log warning if the discriminator points to the base type itself as this is implicitly the default case. 
+            if (!baseClass.Equals(result.TypeDefinition))// don't log warning if the discriminator points to the base type itself as this is implicitly the default case.
                 logger.LogWarning("Discriminator {ComponentKey} is not inherited from {ClassName}.", componentKey, baseClass.Name);
             return null;
         }


Test patch:
diff --git a/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs b/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs
index 6ca611be28..db1ff23416 100644
--- a/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs
+++ b/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs
@@ -673,6 +673,351 @@ public void MergesIntersectionRecursively()
         Assert.Equal("description", result.Description);
         Assert.True(result.Deprecated);
     }
+
+    public class MergeSingleInclusiveUnionInheritanceOrIntersectionSchemaEntries
+    {
+        [Fact]
+        public void DoesMergeWithInheritance()
+        {
+            var schema = new OpenApiSchema()
+            {
+                Type = "object",
+                AnyOf =
+                [
+                    new()
+                    {
+                        Properties = new Dictionary<string, OpenApiSchema>()
+                        {
+                            ["one"] = new OpenApiSchema(),
+                        },
+                        AllOf =
+                        [
+                            new()
+                            {
+                                Reference = new()
+                                {
+                                    Id = "BaseClass"
+                                },
+                            },
+                            new()
+                            {
+                                Type = "object",
+                                Properties = new Dictionary<string, OpenApiSchema>()
+                                {
+                                    ["firstName"] = new OpenApiSchema(),
+                                    ["lastName"] = new OpenApiSchema()
+                                }
+                            },
+                        ]
+                    },
+                ],
+            };
+
+            var result = schema.MergeSingleInclusiveUnionInheritanceOrIntersectionSchemaEntries();
+            Assert.True(schema.AnyOf[0].IsInherited());
+            Assert.NotNull(result);
+            Assert.True(result.IsInherited());
+            Assert.Contains("one", result.Properties.Keys);
+            Assert.Empty(result.AnyOf);
+            Assert.Equal(2, result.AllOf.Count);
+        }
+        [Fact]
+        public void DoesMergeWithIntersection()
+        {
+            var schema = new OpenApiSchema()
+            {
+                Type = "object",
+                AnyOf =
+                [
+                    new()
+                    {
+                        Properties = new Dictionary<string, OpenApiSchema>()
+                        {
+                            ["one"] = new OpenApiSchema(),
+                        },
+                        AllOf =
+                        [
+                            new()
+                            {
+                                Type = "object",
+                                Properties = new Dictionary<string, OpenApiSchema>()
+                                {
+                                    ["first"] = new OpenApiSchema(),
+                                }
+                            },
+                            new()
+                            {
+                                Type = "object",
+                                Properties = new Dictionary<string, OpenApiSchema>()
+                                {
+                                    ["second"] = new OpenApiSchema(),
+                                }
+                            },
+                            new()
+                            {
+                                Type = "object",
+                                Properties = new Dictionary<string, OpenApiSchema>()
+                                {
+                                    ["third"] = new OpenApiSchema(),
+                                }
+                            },
+                        ]
+                    },
+                ],
+            };
+
+            var result = schema.MergeSingleInclusiveUnionInheritanceOrIntersectionSchemaEntries();
+            Assert.NotNull(result);
+            Assert.True(schema.AnyOf[0].IsIntersection());
+            Assert.True(result.IsIntersection());
+            Assert.Contains("one", result.Properties.Keys);
+            Assert.Empty(result.AnyOf);
+            Assert.Equal(3, result.AllOf.Count);
+        }
+        [Fact]
+        public void DoesNotMergeWithMoreThanOneInclusiveEntry()
+        {
+            var schema = new OpenApiSchema()
+            {
+                Type = "object",
+                AnyOf =
+                [
+                    new()
+                    {
+                        Properties = new Dictionary<string, OpenApiSchema>()
+                        {
+                            ["one"] = new OpenApiSchema(),
+                        },
+                        AllOf =
+                        [
+                            new()
+                            {
+                                Reference = new()
+                                {
+                                    Id = "BaseClass"
+                                },
+                            },
+                            new()
+                            {
+                                Type = "object",
+                                Properties = new Dictionary<string, OpenApiSchema>()
+                                {
+                                    ["firstName"] = new OpenApiSchema(),
+                                    ["lastName"] = new OpenApiSchema()
+                                }
+                            },
+                        ]
+                    },
+                    new() { Type = "object" },
+                ],
+            };
+
+            var result = schema.MergeSingleInclusiveUnionInheritanceOrIntersectionSchemaEntries();
+            Assert.Null(result);
+        }
+        [Fact]
+        public void DoesNotMergeWithoutInheritanceOrIntersection()
+        {
+            var schema = new OpenApiSchema()
+            {
+                Type = "object",
+                AnyOf =
+                [
+                    new()
+                    {
+                        AllOf =
+                        [
+                            new()
+                            {
+                                Type = "object",
+                                Properties = new Dictionary<string, OpenApiSchema>()
+                                {
+                                    ["firstName"] = new OpenApiSchema(),
+                                    ["lastName"] = new OpenApiSchema()
+                                }
+                            },
+                        ]
+                    },
+                ],
+            };
+
+            var result = schema.MergeSingleInclusiveUnionInheritanceOrIntersectionSchemaEntries();
+            Assert.Null(result);
+        }
+    }
+
+    public class MergeSingleExclusiveUnionInheritanceOrIntersectionSchemaEntries
+    {
+        [Fact]
+        public void DoesMergeWithInheritance()
+        {
+            var schema = new OpenApiSchema()
+            {
+                Type = "object",
+                OneOf =
+                [
+                    new()
+                    {
+                        Properties = new Dictionary<string, OpenApiSchema>()
+                        {
+                            ["one"] = new OpenApiSchema(),
+                        },
+                        AllOf =
+                        [
+                            new()
+                            {
+                                Reference = new()
+                                {
+                                    Id = "BaseClass"
+                                },
+                            },
+                            new()
+                            {
+                                Type = "object",
+                                Properties = new Dictionary<string, OpenApiSchema>()
+                                {
+                                    ["firstName"] = new OpenApiSchema(),
+                                    ["lastName"] = new OpenApiSchema()
+                                }
+                            },
+                        ]
+                    },
+                ],
+            };
+
+            var result = schema.MergeSingleExclusiveUnionInheritanceOrIntersectionSchemaEntries();
+            Assert.True(schema.OneOf[0].IsInherited());
+            Assert.NotNull(result);
+            Assert.True(result.IsInherited());
+            Assert.Contains("one", result.Properties.Keys);
+            Assert.Empty(result.OneOf);
+            Assert.Equal(2, result.AllOf.Count);
+        }
+        [Fact]
+        public void DoesMergeWithIntersection()
+        {
+            var schema = new OpenApiSchema()
+            {
+                Type = "object",
+                OneOf =
+                [
+                    new()
+                    {
+                        Properties = new Dictionary<string, OpenApiSchema>()
+                        {
+                            ["one"] = new OpenApiSchema(),
+                        },
+                        AllOf =
+                        [
+                            new()
+                            {
+                                Type = "object",
+                                Properties = new Dictionary<string, OpenApiSchema>()
+                                {
+                                    ["first"] = new OpenApiSchema(),
+                                }
+                            },
+                            new()
+                            {
+                                Type = "object",
+                                Properties = new Dictionary<string, OpenApiSchema>()
+                                {
+                                    ["second"] = new OpenApiSchema(),
+                                }
+                            },
+                            new()
+                            {
+                                Type = "object",
+                                Properties = new Dictionary<string, OpenApiSchema>()
+                                {
+                                    ["third"] = new OpenApiSchema(),
+                                }
+                            },
+                        ]
+                    },
+                ],
+            };
+
+            var result = schema.MergeSingleExclusiveUnionInheritanceOrIntersectionSchemaEntries();
+            Assert.NotNull(result);
+            Assert.True(schema.OneOf[0].IsIntersection());
+            Assert.True(result.IsIntersection());
+            Assert.Contains("one", result.Properties.Keys);
+            Assert.Empty(result.OneOf);
+            Assert.Equal(3, result.AllOf.Count);
+        }
+        [Fact]
+        public void DoesNotMergeWithMoreThanOneExclusiveEntry()
+        {
+            var schema = new OpenApiSchema()
+            {
+                Type = "object",
+                OneOf =
+                [
+                    new()
+                    {
+                        Properties = new Dictionary<string, OpenApiSchema>()
+                        {
+                            ["one"] = new OpenApiSchema(),
+                        },
+                        AllOf =
+                        [
+                            new()
+                            {
+                                Reference = new()
+                                {
+                                    Id = "BaseClass"
+                                },
+                            },
+                            new()
+                            {
+                                Type = "object",
+                                Properties = new Dictionary<string, OpenApiSchema>()
+                                {
+                                    ["firstName"] = new OpenApiSchema(),
+                                    ["lastName"] = new OpenApiSchema()
+                                }
+                            },
+                        ]
+                    },
+                    new() { Type = "object" },
+                ],
+            };
+
+            var result = schema.MergeSingleExclusiveUnionInheritanceOrIntersectionSchemaEntries();
+            Assert.Null(result);
+        }
+        [Fact]
+        public void DoesNotMergeWithoutInheritanceOrIntersection()
+        {
+            var schema = new OpenApiSchema()
+            {
+                Type = "object",
+                OneOf =
+                [
+                    new()
+                    {
+                        AllOf =
+                        [
+                            new()
+                            {
+                                Type = "object",
+                                Properties = new Dictionary<string, OpenApiSchema>()
+                                {
+                                    ["firstName"] = new OpenApiSchema(),
+                                    ["lastName"] = new OpenApiSchema()
+                                }
+                            },
+                        ]
+                    },
+                ],
+            };
+
+            var result = schema.MergeSingleExclusiveUnionInheritanceOrIntersectionSchemaEntries();
+            Assert.Null(result);
+        }
+    }
+
     [Fact]
     public void IsArrayFalseOnEmptyItems()
     {
diff --git a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs
index a62089926f..7acf60fbb3 100644
--- a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs
+++ b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs
@@ -8619,11 +8619,266 @@ public async Task ExclusiveUnionSingleEntriesMergingAsync()
         Assert.NotNull(oneProperty);
 
         var withoutObjectClass = codeModel.FindChildByName<CodeClass>("Component2");
-        Assert.NotNull(withObjectClass);
+        Assert.NotNull(withoutObjectClass);
         var twoProperty = withoutObjectClass.FindChildByName<CodeProperty>("two", false);
         Assert.NotNull(twoProperty);
     }
 
+    [Fact]
+    public async Task ExclusiveUnionInheritanceEntriesMergingAsync()
+    {
+        var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
+        await using var fs = await GetDocumentStreamAsync(
+"""
+openapi: 3.0.0
+info:
+  title: "Generator not generating oneOf if the containing schema has type: object"
+  version: "1.0.0"
+servers:
+  - url: https://mytodos.doesnotexist/
+paths:
+  /uses-components:
+    post:
+      description: Return something
+      responses:
+        "200":
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/UsesComponents"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/UsesComponents"
+components:
+  schemas:
+    ExampleWithSingleOneOfWithTypeObject:
+      description: "ExampleWithSingleOneOfWithTypeObject"
+      type: object
+      oneOf:
+        - $ref: "#/components/schemas/Component1"
+      discriminator:
+        propertyName: objectType
+
+    ExampleWithSingleOneOfWithoutTypeObject:
+      description: "ExampleWithSingleOneOfWithoutTypeObject"
+      oneOf:
+        - $ref: "#/components/schemas/Component2"
+      discriminator:
+        propertyName: objectType
+
+    UsesComponents:
+      type: object
+      properties:
+        component_with_single_oneof_with_type_object:
+          $ref: "#/components/schemas/ExampleWithSingleOneOfWithTypeObject"
+        component_with_single_oneof_without_type_object:
+          $ref: "#/components/schemas/ExampleWithSingleOneOfWithoutTypeObject"
+
+    ComponentCommon:
+      description: "ComponentCommon"
+      type: object
+      required:
+        - objectType
+      properties:
+        objectType:
+          type: string
+        common:
+          type: string
+
+    Component1:
+      description: "Component1"
+      type: object
+      allOf:
+        - $ref: "#/components/schemas/ComponentCommon"
+        - type: object
+          description: "Component1Inner"
+          properties:
+            one:
+              type: string
+      properties:
+        anotherOne:
+          type: string
+
+    Component2:
+      description: "Component2"
+      type: object
+      allOf:
+        - $ref: "#/components/schemas/ComponentCommon"
+        - type: object
+          description: "Component2Inner"
+          properties:
+            two:
+              type: string
+      properties:
+        anotherTwo:
+          type: string
+""");
+        var mockLogger = new Mock<ILogger<KiotaBuilder>>();
+        var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", OpenAPIFilePath = tempFilePath }, _httpClient);
+        var document = await builder.CreateOpenApiDocumentAsync(fs);
+        var node = builder.CreateUriSpace(document);
+        var codeModel = builder.CreateSourceModel(node);
+
+        // Verify that all three classes referenced by the discriminator inherit from baseDirectoryObject
+        var withObjectClass = codeModel.FindChildByName<CodeClass>("ExampleWithSingleOneOfWithTypeObject");
+        Assert.NotNull(withObjectClass);
+        // ExampleWithSingleOneOfWithTypeObject inherits from ComponentCommon
+        Assert.Equal("ComponentCommon", withObjectClass.BaseClass?.Name);
+        var withObjectClassOneProperty = withObjectClass.FindChildByName<CodeProperty>("one", false);
+        Assert.NotNull(withObjectClassOneProperty);
+        var withObjectClassAnotherOneProperty = withObjectClass.FindChildByName<CodeProperty>("anotherOne", false);
+        Assert.NotNull(withObjectClassAnotherOneProperty);
+
+        var withoutObjectClass = codeModel.FindChildByName<CodeClass>("Component2");
+        Assert.NotNull(withoutObjectClass);
+        // Component2 inherits from ComponentCommon
+        Assert.Equal("ComponentCommon", withoutObjectClass.BaseClass?.Name);
+        var withoutObjectClassTwoProperty = withoutObjectClass.FindChildByName<CodeProperty>("two", false);
+        Assert.NotNull(withoutObjectClassTwoProperty);
+        var withoutObjectClassClassAnotherTwoProperty = withoutObjectClass.FindChildByName<CodeProperty>("anotherTwo", false);
+        Assert.NotNull(withoutObjectClassClassAnotherTwoProperty);
+    }
+
+    [Fact]
+    public async Task ExclusiveUnionIntersectionEntriesMergingAsync()
+    {
+        var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
+        await using var fs = await GetDocumentStreamAsync(
+"""
+openapi: 3.0.0
+info:
+  title: "Generator not generating oneOf if the containing schema has type: object"
+  version: "1.0.0"
+servers:
+  - url: https://mytodos.doesnotexist/
+paths:
+  /uses-components:
+    post:
+      description: Return something
+      responses:
+        "200":
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/UsesComponents"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/UsesComponents"
+components:
+  schemas:
+    ExampleWithSingleOneOfWithTypeObject:
+      description: "ExampleWithSingleOneOfWithTypeObject"
+      type: object
+      oneOf:
+        - $ref: "#/components/schemas/Component1"
+      discriminator:
+        propertyName: objectType
+
+    ExampleWithSingleOneOfWithoutTypeObject:
+      description: "ExampleWithSingleOneOfWithoutTypeObject"
+      oneOf:
+        - $ref: "#/components/schemas/Component2"
+      discriminator:
+        propertyName: objectType
+
+    UsesComponents:
+      type: object
+      properties:
+        component_with_single_oneof_with_type_object:
+          $ref: "#/components/schemas/ExampleWithSingleOneOfWithTypeObject"
+        component_with_single_oneof_without_type_object:
+          $ref: "#/components/schemas/ExampleWithSingleOneOfWithoutTypeObject"
+
+    ComponentCommon:
+      description: "ComponentCommon"
+      type: object
+      required:
+        - objectType
+      properties:
+        objectType:
+          type: string
+        common:
+          type: string
+
+    ComponentCommon2:
+      description: "ComponentCommon2"
+      type: object
+      properties:
+        common2:
+          type: string
+
+    Component1:
+      description: "Component1"
+      type: object
+      allOf:
+        - $ref: "#/components/schemas/ComponentCommon"
+        - $ref: "#/components/schemas/ComponentCommon2"
+        - type: object
+          description: "Component1Self"
+          properties:
+            one:
+              type: string
+      properties:
+        anotherOne:
+          type: string
+
+    Component2:
+      description: "Component2"
+      type: object
+      required:
+        - objectType
+      allOf:
+        - $ref: "#/components/schemas/ComponentCommon"
+        - $ref: "#/components/schemas/ComponentCommon2"
+        - type: object
+          description: "Component2Self"
+          properties:
+            two:
+              type: string
+      properties:
+        anotherTwo:
+          type: string
+""");
+        var mockLogger = new Mock<ILogger<KiotaBuilder>>();
+        var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", OpenAPIFilePath = tempFilePath }, _httpClient);
+        var document = await builder.CreateOpenApiDocumentAsync(fs);
+        var node = builder.CreateUriSpace(document);
+        var codeModel = builder.CreateSourceModel(node);
+
+        // Verify both scenarios have all the properties available from all schemas
+        var withObjectClass = codeModel.FindChildByName<CodeClass>("ExampleWithSingleOneOfWithTypeObject");
+        Assert.NotNull(withObjectClass);
+        var withObjectClassOneProperty = withObjectClass.FindChildByName<CodeProperty>("one", false);
+        Assert.NotNull(withObjectClassOneProperty);
+        var withObjectClassCommonProperty = withObjectClass.FindChildByName<CodeProperty>("common", false);
+        Assert.NotNull(withObjectClassCommonProperty);
+        var withObjectClassCommon2Property = withObjectClass.FindChildByName<CodeProperty>("common2", false);
+        Assert.NotNull(withObjectClassCommon2Property);
+        var withObjectClassObjectTypeProperty = withObjectClass.FindChildByName<CodeProperty>("objectType", false);
+        Assert.NotNull(withObjectClassObjectTypeProperty);
+        var withObjectClassAnotherOneProperty = withObjectClass.FindChildByName<CodeProperty>("anotherOne", false);
+        Assert.NotNull(withObjectClassAnotherOneProperty);
+
+        var withoutObjectClass = codeModel.FindChildByName<CodeClass>("Component2");
+        Assert.NotNull(withoutObjectClass);
+        var withoutObjectClassTwoProperty = withoutObjectClass.FindChildByName<CodeProperty>("two", false);
+        Assert.NotNull(withoutObjectClassTwoProperty);
+        var withoutObjectClassCommonProperty = withoutObjectClass.FindChildByName<CodeProperty>("common", false);
+        Assert.NotNull(withoutObjectClassCommonProperty);
+        var withoutObjectClassCommon2Property = withoutObjectClass.FindChildByName<CodeProperty>("common2", false);
+        Assert.NotNull(withoutObjectClassCommon2Property);
+        var withoutObjectClassObjectTypeProperty = withoutObjectClass.FindChildByName<CodeProperty>("objectType", false);
+        Assert.NotNull(withoutObjectClassObjectTypeProperty);
+        var withoutObjectClassClassAnotherTwoProperty = withoutObjectClass.FindChildByName<CodeProperty>("anotherTwo", false);
+        Assert.NotNull(withoutObjectClassClassAnotherTwoProperty);
+    }
+
     [Fact]
     public async Task InclusiveUnionSingleEntriesMergingAsync()
     {
@@ -8712,6 +8967,261 @@ public async Task InclusiveUnionSingleEntriesMergingAsync()
         Assert.NotNull(twoProperty);
     }
 
+    [Fact]
+    public async Task InclusiveUnionInheritanceEntriesMergingAsync()
+    {
+        var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
+        await using var fs = await GetDocumentStreamAsync(
+"""
+openapi: 3.0.0
+info:
+  title: "Generator not generating oneOf if the containing schema has type: object"
+  version: "1.0.0"
+servers:
+  - url: https://mytodos.doesnotexist/
+paths:
+  /uses-components:
+    post:
+      description: Return something
+      responses:
+        "200":
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/UsesComponents"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/UsesComponents"
+components:
+  schemas:
+    ExampleWithSingleOneOfWithTypeObject:
+      description: "ExampleWithSingleOneOfWithTypeObject"
+      type: object
+      anyOf:
+        - $ref: "#/components/schemas/Component1"
+      discriminator:
+        propertyName: objectType
+
+    ExampleWithSingleOneOfWithoutTypeObject:
+      description: "ExampleWithSingleOneOfWithoutTypeObject"
+      anyOf:
+        - $ref: "#/components/schemas/Component2"
+      discriminator:
+        propertyName: objectType
+
+    UsesComponents:
+      type: object
+      properties:
+        component_with_single_oneof_with_type_object:
+          $ref: "#/components/schemas/ExampleWithSingleOneOfWithTypeObject"
+        component_with_single_oneof_without_type_object:
+          $ref: "#/components/schemas/ExampleWithSingleOneOfWithoutTypeObject"
+
+    ComponentCommon:
+      description: "ComponentCommon"
+      type: object
+      required:
+        - objectType
+      properties:
+        objectType:
+          type: string
+        common:
+          type: string
+
+    Component1:
+      description: "Component1"
+      type: object
+      allOf:
+        - $ref: "#/components/schemas/ComponentCommon"
+        - type: object
+          description: "Component1Inner"
+          properties:
+            one:
+              type: string
+      properties:
+        anotherOne:
+          type: string
+
+    Component2:
+      description: "Component2"
+      type: object
+      allOf:
+        - $ref: "#/components/schemas/ComponentCommon"
+        - type: object
+          description: "Component2Inner"
+          properties:
+            two:
+              type: string
+      properties:
+        anotherTwo:
+          type: string
+""");
+        var mockLogger = new Mock<ILogger<KiotaBuilder>>();
+        var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", OpenAPIFilePath = tempFilePath }, _httpClient);
+        var document = await builder.CreateOpenApiDocumentAsync(fs);
+        var node = builder.CreateUriSpace(document);
+        var codeModel = builder.CreateSourceModel(node);
+
+        // Verify that all three classes referenced by the discriminator inherit from baseDirectoryObject
+        var withObjectClass = codeModel.FindChildByName<CodeClass>("ExampleWithSingleOneOfWithTypeObject");
+        Assert.NotNull(withObjectClass);
+        // ExampleWithSingleOneOfWithTypeObject inherits from ComponentCommon
+        Assert.Equal("ComponentCommon", withObjectClass.BaseClass?.Name);
+        var withObjectClassOneProperty = withObjectClass.FindChildByName<CodeProperty>("one", false);
+        Assert.NotNull(withObjectClassOneProperty);
+        var withObjectClassAnotherOneProperty = withObjectClass.FindChildByName<CodeProperty>("anotherOne", false);
+        Assert.NotNull(withObjectClassAnotherOneProperty);
+
+        var withoutObjectClass = codeModel.FindChildByName<CodeClass>("Component2");
+        Assert.NotNull(withoutObjectClass);
+        // Component2 inherits from ComponentCommon
+        Assert.Equal("ComponentCommon", withoutObjectClass.BaseClass?.Name);
+        var withoutObjectClassTwoProperty = withoutObjectClass.FindChildByName<CodeProperty>("two", false);
+        Assert.NotNull(withoutObjectClassTwoProperty);
+        var withoutObjectClassClassAnotherTwoProperty = withoutObjectClass.FindChildByName<CodeProperty>("anotherTwo", false);
+        Assert.NotNull(withoutObjectClassClassAnotherTwoProperty);
+    }
+
+    [Fact]
+    public async Task InclusiveUnionIntersectionEntriesMergingAsync()
+    {
+        var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
+        await using var fs = await GetDocumentStreamAsync(
+"""
+openapi: 3.0.0
+info:
+  title: "Generator not generating oneOf if the containing schema has type: object"
+  version: "1.0.0"
+servers:
+  - url: https://mytodos.doesnotexist/
+paths:
+  /uses-components:
+    post:
+      description: Return something
+      responses:
+        "200":
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/UsesComponents"
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/UsesComponents"
+components:
+  schemas:
+    ExampleWithSingleOneOfWithTypeObject:
+      description: "ExampleWithSingleOneOfWithTypeObject"
+      type: object
+      anyOf:
+        - $ref: "#/components/schemas/Component1"
+      discriminator:
+        propertyName: objectType
+
+    ExampleWithSingleOneOfWithoutTypeObject:
+      description: "ExampleWithSingleOneOfWithoutTypeObject"
+      anyOf:
+        - $ref: "#/components/schemas/Component2"
+      discriminator:
+        propertyName: objectType
+
+    UsesComponents:
+      type: object
+      properties:
+        component_with_single_oneof_with_type_object:
+          $ref: "#/components/schemas/ExampleWithSingleOneOfWithTypeObject"
+        component_with_single_oneof_without_type_object:
+          $ref: "#/components/schemas/ExampleWithSingleOneOfWithoutTypeObject"
+
+    ComponentCommon:
+      description: "ComponentCommon"
+      type: object
+      required:
+        - objectType
+      properties:
+        objectType:
+          type: string
+        common:
+          type: string
+
+    ComponentCommon2:
+      description: "ComponentCommon2"
+      type: object
+      properties:
+        common2:
+          type: string
+
+    Component1:
+      description: "Component1"
+      type: object
+      allOf:
+        - $ref: "#/components/schemas/ComponentCommon"
+        - $ref: "#/components/schemas/ComponentCommon2"
+        - type: object
+          description: "Component1Self"
+          properties:
+            one:
+              type: string
+      properties:
+        anotherOne:
+          type: string
+
+    Component2:
+      description: "Component2"
+      type: object
+      required:
+        - objectType
+      allOf:
+        - $ref: "#/components/schemas/ComponentCommon"
+        - $ref: "#/components/schemas/ComponentCommon2"
+        - type: object
+          description: "Component2Self"
+          properties:
+            two:
+              type: string
+      properties:
+        anotherTwo:
+          type: string
+""");
+        var mockLogger = new Mock<ILogger<KiotaBuilder>>();
+        var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", OpenAPIFilePath = tempFilePath }, _httpClient);
+        var document = await builder.CreateOpenApiDocumentAsync(fs);
+        var node = builder.CreateUriSpace(document);
+        var codeModel = builder.CreateSourceModel(node);
+
+        // Verify both scenarios have all the properties available from all schemas
+        var withObjectClass = codeModel.FindChildByName<CodeClass>("ExampleWithSingleOneOfWithTypeObject");
+        Assert.NotNull(withObjectClass);
+        var withObjectClassOneProperty = withObjectClass.FindChildByName<CodeProperty>("one", false);
+        Assert.NotNull(withObjectClassOneProperty);
+        var withObjectClassCommonProperty = withObjectClass.FindChildByName<CodeProperty>("common", false);
+        Assert.NotNull(withObjectClassCommonProperty);
+        var withObjectClassCommon2Property = withObjectClass.FindChildByName<CodeProperty>("common2", false);
+        Assert.NotNull(withObjectClassCommon2Property);
+        var withObjectClassObjectTypeProperty = withObjectClass.FindChildByName<CodeProperty>("objectType", false);
+        Assert.NotNull(withObjectClassObjectTypeProperty);
+        var withObjectClassAnotherOneProperty = withObjectClass.FindChildByName<CodeProperty>("anotherOne", false);
+        Assert.NotNull(withObjectClassAnotherOneProperty);
+
+        var withoutObjectClass = codeModel.FindChildByName<CodeClass>("Component2");
+        Assert.NotNull(withoutObjectClass);
+        var withoutObjectClassTwoProperty = withoutObjectClass.FindChildByName<CodeProperty>("two", false);
+        Assert.NotNull(withoutObjectClassTwoProperty);
+        var withoutObjectClassCommonProperty = withoutObjectClass.FindChildByName<CodeProperty>("common", false);
+        Assert.NotNull(withoutObjectClassCommonProperty);
+        var withoutObjectClassCommon2Property = withoutObjectClass.FindChildByName<CodeProperty>("common2", false);
+        Assert.NotNull(withoutObjectClassCommon2Property);
+        var withoutObjectClassObjectTypeProperty = withoutObjectClass.FindChildByName<CodeProperty>("objectType", false);
+        Assert.NotNull(withoutObjectClassObjectTypeProperty);
+        var withoutObjectClassClassAnotherTwoProperty = withoutObjectClass.FindChildByName<CodeProperty>("anotherTwo", false);
+        Assert.NotNull(withoutObjectClassClassAnotherTwoProperty);
+    }
+
     [Fact]
     public async Task NestedIntersectionTypeAllOfAsync()
     {
@@ -9022,14 +9532,14 @@ public async Task InheritanceWithAllOfWith3Parts1Schema2InlineAsync(bool reverse
           '#microsoft.graph.group': '#/components/schemas/microsoft.graph.group'
     microsoft.graph.group:
       allOf:"
-       + (reverseOrder ? "" : @" 
+       + (reverseOrder ? "" : @"
         - '$ref': '#/components/schemas/microsoft.graph.directoryObject'") + @"
         - properties:
             groupprop1:
               type: 'string'
         - properties:
             groupprop2:
-              type: 'string'" + (!reverseOrder ? "" : @" 
+              type: 'string'" + (!reverseOrder ? "" : @"
         - '$ref': '#/components/schemas/microsoft.graph.directoryObject'"));
         var mockLogger = new Mock<ILogger<KiotaBuilder>>();
         var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", OpenAPIFilePath = tempFilePath }, _httpClient);