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; } +}