diff --git a/README.md b/README.md
index 69bb509..2d66ad1 100644
--- a/README.md
+++ b/README.md
@@ -76,6 +76,35 @@ public class ExamplesRepository : IExamplesRepository
}
```
+You can also join a table on itself:
+
+```c#
+using System;
+using Snowflake.Data.Xt;
+
+namespace SnowflakeApplication;
+
+[SnowflakeTable(
+ name: "COST_CENTER",
+ alias: "costCenter1")]
+[SnowflakeJoin(
+ table: "COST_CENTER",
+ alias: "costCenter2",
+ type: SnowflakeJoinAttribute.Left,
+ condition: "costCenter1.COST_CENTER_ID = costCenter2.COST_CENTER_ID")]
+public class Example
+{
+ [SnowflakeColumn(name: "VALUE")]
+ public decimal Value { get; set; }
+
+ [SnowflakeColumn(name: "ADDRESS", table: "COST_CENTER")]
+ public string Address { get; set; }
+
+ [SnowflakeColumn(name: "IS_READY", table: "COST_CENTER", alias: "costCenter2")] // Alias must be provided
+ public bool IsReady { get; set; }
+}
+```
+
You can also reuse a snowflake database connection:
```c#
diff --git a/src/Attributes/SnowflakeColumnAttribute.cs b/src/Attributes/SnowflakeColumnAttribute.cs
index 1d7c4d4..ffdf387 100644
--- a/src/Attributes/SnowflakeColumnAttribute.cs
+++ b/src/Attributes/SnowflakeColumnAttribute.cs
@@ -18,12 +18,19 @@ public sealed class SnowflakeColumnAttribute : Attribute
///
/// The name.
/// The table.
- public SnowflakeColumnAttribute(string? name = default, string? table = default)
+ /// The alias.
+ public SnowflakeColumnAttribute(string? name = default, string? table = default, string? alias = default)
{
+ this.Alias = alias;
this.Name = name ?? string.Empty;
this.Table = table;
}
+ ///
+ /// Gets the alias.
+ ///
+ public string? Alias { get; internal set; }
+
///
/// Gets the name.
///
diff --git a/src/Command/SnowflakeCommand.cs b/src/Command/SnowflakeCommand.cs
index a567e5c..2829518 100644
--- a/src/Command/SnowflakeCommand.cs
+++ b/src/Command/SnowflakeCommand.cs
@@ -184,8 +184,9 @@ protected string Columns
{
var column = property.Value;
var table = column.Table ?? this.Table.Name;
- var tableAlias = string.Equals(this.Table.Name, table, StringComparison.Ordinal) ? this.Table.Alias ?? string.Empty
- : this.Joins.SingleOrDefault(join => string.Equals(join.Table, table, StringComparison.Ordinal))?.Alias ?? string.Empty;
+ var tableAlias = column.Alias ?? (string.Equals(this.Table.Name, table, StringComparison.Ordinal)
+ ? this.Table.Alias ?? string.Empty
+ : this.Joins.SingleOrDefault(join => string.Equals(join.Table, table, StringComparison.Ordinal))?.Alias ?? string.Empty);
columns.Append($"{tableAlias}{(string.IsNullOrWhiteSpace(tableAlias) ? string.Empty : ".")}{column.Name}, ");
}
diff --git a/tests/Command/SnowflakeCommand.Tests.cs b/tests/Command/SnowflakeCommand.Tests.cs
index 12eb1ec..f874f1d 100644
--- a/tests/Command/SnowflakeCommand.Tests.cs
+++ b/tests/Command/SnowflakeCommand.Tests.cs
@@ -27,4 +27,17 @@ public void Constructor_ShouldFill_SELECT_FROM_JOIN_ForClassWithJoin()
// Assert
sql.Should().Be("SELECT bar.ID, foo.PROP_1, bar.Prop_2 FROM DATABASE.SCHEMA.BAR AS bar LEFT JOIN DATABASE.SCHEMA.FOO AS foo ON bar.ID = foo.ID");
}
+
+ [Fact]
+ public void Constructor_ShouldFill_SELECT_FROM_JOIN_ForClassWithJoinOnItself()
+ {
+ // Arrange
+ var command = new SnowflakeCommand("DATABASE", "SCHEMA");
+
+ // Act
+ var sql = command.Sql;
+
+ // Assert
+ sql.Should().Be("SELECT bar1.ID, bar1.PROP_1, bar2.Prop_2 FROM DATABASE.SCHEMA.BAR AS bar1 LEFT JOIN DATABASE.SCHEMA.BAR AS bar2 ON bar1.ID = bar2.ID");
+ }
}
diff --git a/tests/TestClasses.cs b/tests/TestClasses.cs
index 2ed6df3..27f8ac5 100644
--- a/tests/TestClasses.cs
+++ b/tests/TestClasses.cs
@@ -29,3 +29,23 @@ internal sealed class SnowflakeClass2
[SnowflakeColumn]
public string? Prop_2 { get; set; }
}
+
+[SnowflakeTable(
+ name: "BAR",
+ alias: "bar1")]
+[SnowflakeJoin(
+ table: "BAR",
+ alias: "bar2",
+ type: SnowflakeJoinAttribute.Left,
+ condition: "bar1.ID = bar2.ID")]
+internal sealed class SnowflakeClass3
+{
+ [SnowflakeColumn("ID")]
+ public int Id { get; set; }
+
+ [SnowflakeColumn("PROP_1", "BAR")]
+ public string? Property1 { get; set; }
+
+ [SnowflakeColumn("Prop_2", "BAR", "bar2")]
+ public string? Prop_2 { get; set; }
+}