From b860f0aca8da16657f0117d4d2e5cf28e2d4ddab Mon Sep 17 00:00:00 2001 From: Austin Drenski Date: Fri, 25 May 2018 10:06:16 -0400 Subject: [PATCH] Adds network address (cidr and inet) functions for translation - Maps cidr and inet functions to CLR extension methods. - See: https://www.postgresql.org/docs/current/static/functions-net.html#CIDR-INET-FUNCTIONS-TABLE - Includes functional tests covering translation. - Includes the bug fix in #425. - This can be removed once #425 is merged. --- .../NpgsqlNetworkAddressExtensions.cs | 326 ++++++++++++- .../NpgsqlNetworkAddressTranslator.cs | 37 ++ .../Query/NetworkAddressQueryNpgsqlTest.cs | 428 +++++++++++++++++- 3 files changed, 785 insertions(+), 6 deletions(-) diff --git a/src/EFCore.PG/Extensions/NpgsqlNetworkAddressExtensions.cs b/src/EFCore.PG/Extensions/NpgsqlNetworkAddressExtensions.cs index 5560a9af68..f74d6e01b7 100644 --- a/src/EFCore.PG/Extensions/NpgsqlNetworkAddressExtensions.cs +++ b/src/EFCore.PG/Extensions/NpgsqlNetworkAddressExtensions.cs @@ -40,7 +40,7 @@ public static class NpgsqlNetworkAddressExtensions /// Determines whether an contains another . /// /// The instance. - /// The IP address to search. + /// The IP address to search. /// The IP address to locate. /// /// True if the contains the other ; otherwise, false. @@ -48,7 +48,7 @@ public static class NpgsqlNetworkAddressExtensions /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static bool Contains([CanBeNull] this DbFunctions _, IPAddress ipAddress, IPAddress other) => throw new ClientEvaluationNotSupportedException(); + public static bool Contains([CanBeNull] this DbFunctions _, IPAddress inet, IPAddress other) => throw new ClientEvaluationNotSupportedException(); /// /// Determines whether an (IPAddress Address, int Subnet) contains another (IPAddress Address, int Subnet). @@ -68,7 +68,7 @@ public static class NpgsqlNetworkAddressExtensions /// Determines whether an contains or is equal to another . /// /// The instance. - /// The IP address to search. + /// The IP address to search. /// The IP address to locate. /// /// True if the contains or is equal to the other ; otherwise, false. @@ -76,7 +76,7 @@ public static class NpgsqlNetworkAddressExtensions /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static bool ContainsOrEqual([CanBeNull] this DbFunctions _, IPAddress ipAddress, IPAddress other) => throw new ClientEvaluationNotSupportedException(); + public static bool ContainsOrEqual([CanBeNull] this DbFunctions _, IPAddress inet, IPAddress other) => throw new ClientEvaluationNotSupportedException(); /// /// Determines whether an (IPAddress Address, int Subnet) contains or is equal to another (IPAddress Address, int Subnet). @@ -481,5 +481,323 @@ public static class NpgsqlNetworkAddressExtensions /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static (IPAddress Address, int Subnet) Subtract([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Returns the abbreviated display format as text. + /// + /// The instance. + /// The inet to abbreviate. + /// + /// The abbreviated display format as text. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static string Abbreviate([CanBeNull] this DbFunctions _, IPAddress inet) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Returns the abbreviated display format as text. + /// + /// The instance. + /// The cidr to abbreviate. + /// + /// The abbreviated display format as text. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static string Abbreviate([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Returns the broadcast address for a network. + /// + /// The instance. + /// The inet used to derive the broadcast address. + /// + /// The broadcast address for a network. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static IPAddress Broadcast([CanBeNull] this DbFunctions _, IPAddress inet) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Returns the broadcast address for a network. + /// + /// The instance. + /// The cidr used to derive the broadcast address. + /// + /// The broadcast address for a network. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static IPAddress Broadcast([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Extracts the family of an address; 4 for IPv4, 6 for IPv6. + /// + /// The instance. + /// The inet used to derive the family. + /// + /// The family of an address; 4 for IPv4, 6 for IPv6. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static int Family([CanBeNull] this DbFunctions _, IPAddress inet) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Extracts the family of an address; 4 for IPv4, 6 for IPv6. + /// + /// The instance. + /// The cidr used to derive the family. + /// + /// The family of an address; 4 for IPv4, 6 for IPv6. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static int Family([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Extracts the host (i.e. the IP address) as text. + /// + /// The instance. + /// The inet from which to extract the host. + /// + /// The host (i.e. the IP address) as text. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static string Host([CanBeNull] this DbFunctions _, IPAddress inet) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Extracts the host (i.e. the IP address) as text. + /// + /// The instance. + /// The cidr from which to extract the host. + /// + /// The host (i.e. the IP address) as text. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static string Host([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Constructs the host mask for the network. + /// + /// The instance. + /// The inet used to construct the host mask. + /// + /// The constructed host mask. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static IPAddress HostMask([CanBeNull] this DbFunctions _, IPAddress inet) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Constructs the host mask for the network. + /// + /// The instance. + /// The cidr used to construct the host mask. + /// + /// The constructed host mask. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static IPAddress HostMask([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Extracts the length of the subnet mask. + /// + /// The instance. + /// The inet used to extract the subnet length. + /// + /// The length of the subnet mask. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static int SubnetLength([CanBeNull] this DbFunctions _, IPAddress inet) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Extracts the length of the subnet mask. + /// + /// The instance. + /// The cidr used to extract the subnet length. + /// + /// The length of the subnet mask. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static int SubnetLength([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Constructs the subnet mask for the network. + /// + /// The instance. + /// The inet used to construct the subnet mask. + /// + /// The subnet mask for the network. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static IPAddress SubnetMask([CanBeNull] this DbFunctions _, IPAddress inet) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Constructs the subnet mask for the network. + /// + /// The instance. + /// The cidr used to construct the subnet mask. + /// + /// The subnet mask for the network. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static IPAddress SubnetMask([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Extracts the network part of the address. + /// + /// The instance. + /// The inet used to extract the network. + /// + /// The network part of the address. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static (IPAddress Address, int Subnet) Network([CanBeNull] this DbFunctions _, IPAddress inet) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Extracts the network part of the address. + /// + /// The instance. + /// The cidr used to extract the network. + /// + /// The network part of the address. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static (IPAddress Address, int Subnet) Network([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Sets the length of the subnet mask. + /// + /// The instance. + /// The inet to modify. + /// The subnet mask length to set. + /// + /// The network with a subnet mask of the specified length. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static IPAddress SetSubnetLength([CanBeNull] this DbFunctions _, IPAddress inet, int length) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Sets the length of the subnet mask. + /// + /// The instance. + /// The cidr to modify. + /// The subnet mask length to set. + /// + /// The network with a subnet mask of the specified length. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static (IPAddress Address, int Subnet) SetSubnetLength([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, int length) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Extracts the IP address and subnet mask as text. + /// + /// The instance. + /// The inet to extract as text. + /// + /// The IP address and subnet mask as text. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static string Text([CanBeNull] this DbFunctions _, IPAddress inet) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Extracts the IP address and subnet mask as text. + /// + /// The instance. + /// The cidr to extract as text. + /// + /// The IP address and subnet mask as text. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static string Text([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Tests if the addresses are in the same family. + /// + /// The instance. + /// The primary inet. + /// The other inet. + /// + /// True if the addresses are in the same family; otherwise, false. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static bool SameFamily([CanBeNull] this DbFunctions _, IPAddress inet, IPAddress other) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Tests if the addresses are in the same family. + /// + /// The instance. + /// The primary cidr. + /// The other cidr. + /// + /// True if the addresses are in the same family; otherwise, false. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static bool SameFamily([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Constructs the smallest network which includes both of the given networks. + /// + /// The instance. + /// The first inet. + /// The second inet. + /// + /// The smallest network which includes both of the given networks. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static (IPAddress Address, int Subnet) Merge([CanBeNull] this DbFunctions _, IPAddress inet, IPAddress other) => throw new ClientEvaluationNotSupportedException(); + + /// + /// Constructs the smallest network which includes both of the given networks. + /// + /// The instance. + /// The first cidr. + /// The second cidr. + /// + /// The smallest network which includes both of the given networks. + /// + /// + /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. + /// + public static (IPAddress Address, int Subnet) Merge([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) => throw new ClientEvaluationNotSupportedException(); } } diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlNetworkAddressTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlNetworkAddressTranslator.cs index 2348539761..c5feae723c 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlNetworkAddressTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlNetworkAddressTranslator.cs @@ -24,6 +24,7 @@ #endregion using System.Linq.Expressions; +using System.Net; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; @@ -93,6 +94,42 @@ public Expression Translate(MethodCallExpression expression) case nameof(NpgsqlNetworkAddressExtensions.Subtract): return new CustomBinaryExpression(expression.Arguments[1], expression.Arguments[2], "-", expression.Arguments[1].Type); + case nameof(NpgsqlNetworkAddressExtensions.Abbreviate): + return new PgFunctionExpression("abbrev", typeof(string), new[] { expression.Arguments[1] }); + + case nameof(NpgsqlNetworkAddressExtensions.Broadcast): + return new PgFunctionExpression("broadcast", typeof(IPAddress), new[] { expression.Arguments[1] }); + + case nameof(NpgsqlNetworkAddressExtensions.Family): + return new PgFunctionExpression("family", typeof(int), new[] { expression.Arguments[1] }); + + case nameof(NpgsqlNetworkAddressExtensions.Host): + return new PgFunctionExpression("host", typeof(string), new[] { expression.Arguments[1] }); + + case nameof(NpgsqlNetworkAddressExtensions.HostMask): + return new PgFunctionExpression("hostmask", typeof(IPAddress), new[] { expression.Arguments[1] }); + + case nameof(NpgsqlNetworkAddressExtensions.SubnetLength): + return new PgFunctionExpression("masklen", typeof(int), new[] { expression.Arguments[1] }); + + case nameof(NpgsqlNetworkAddressExtensions.SubnetMask): + return new PgFunctionExpression("netmask", typeof(IPAddress), new[] { expression.Arguments[1] }); + + case nameof(NpgsqlNetworkAddressExtensions.Network): + return new PgFunctionExpression("network", typeof((IPAddress Address, int Subnet)), new[] { expression.Arguments[1] }); + + case nameof(NpgsqlNetworkAddressExtensions.SetSubnetLength): + return new PgFunctionExpression("set_masklen", expression.Arguments[1].Type, new[] { expression.Arguments[1], expression.Arguments[2] }); + + case nameof(NpgsqlNetworkAddressExtensions.Text): + return new PgFunctionExpression("text", typeof(string), new[] { expression.Arguments[1] }); + + case nameof(NpgsqlNetworkAddressExtensions.SameFamily): + return new PgFunctionExpression("inet_same_family", typeof(bool), new[] { expression.Arguments[1], expression.Arguments[2] }); + + case nameof(NpgsqlNetworkAddressExtensions.Merge): + return new PgFunctionExpression("inet_merge", typeof((IPAddress Address, int Subnet)), new[] { expression.Arguments[1], expression.Arguments[2] }); + default: return null; } diff --git a/test/EFCore.PG.FunctionalTests/Query/NetworkAddressQueryNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/NetworkAddressQueryNpgsqlTest.cs index 822aad62fd..10afef24ee 100644 --- a/test/EFCore.PG.FunctionalTests/Query/NetworkAddressQueryNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/NetworkAddressQueryNpgsqlTest.cs @@ -31,7 +31,7 @@ public NetworkAddressQueryNpgsqlTest(NetworkAddressQueryNpgsqlFixture fixture) Fixture.TestSqlLoggerFactory.Clear(); } - #region Tests + #region BugTests /// /// Demonstrates parameter duplication. @@ -54,6 +54,10 @@ public void Demonstrate_ValueTypeParametersAreDuplicated() } } + #endregion + + #region OperatorTests + /// /// Tests translation for . /// @@ -208,6 +212,426 @@ public void ValueTuple_cidr_DoesNotContainOrEqual_cidr() #endregion + #region FunctionTests + + /// + /// Tests translation for . + /// + [Fact] + public void IPAddress_inet_Abbreviate() + { + using (NetContext context = Fixture.CreateContext()) + { + string[] _ = + context.NetTestEntities + .Select(x => EF.Functions.Abbreviate(x.Inet)) + .ToArray(); + + AssertContainsSql("SELECT abbrev(x.\"Inet\")"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void ValueTuple_cidr_Abbrebiate() + { + using (NetContext context = Fixture.CreateContext()) + { + string[] _ = + context.NetTestEntities + .Select(x => EF.Functions.Abbreviate(x.Cidr)) + .ToArray(); + + AssertContainsSql("SELECT abbrev(x.\"Cidr\")"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void IPAddress_inet_Broadcast() + { + using (NetContext context = Fixture.CreateContext()) + { + IPAddress[] _ = + context.NetTestEntities + .Select(x => EF.Functions.Broadcast(x.Inet)) + .ToArray(); + + AssertContainsSql("SELECT broadcast(x.\"Inet\")"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void ValueTuple_cidr_Broadcast() + { + using (NetContext context = Fixture.CreateContext()) + { + IPAddress[] _ = + context.NetTestEntities + .Select(x => EF.Functions.Broadcast(x.Cidr)) + .ToArray(); + + AssertContainsSql("SELECT broadcast(x.\"Cidr\")"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void IPAddress_inet_Family() + { + using (NetContext context = Fixture.CreateContext()) + { + int[] _ = + context.NetTestEntities + .Select(x => EF.Functions.Family(x.Inet)) + .ToArray(); + + AssertContainsSql("SELECT family(x.\"Inet\")"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void ValueTuple_cidr_Family() + { + using (NetContext context = Fixture.CreateContext()) + { + int[] _ = + context.NetTestEntities + .Select(x => EF.Functions.Family(x.Cidr)) + .ToArray(); + + AssertContainsSql("SELECT family(x.\"Cidr\")"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void IPAddress_inet_Host() + { + using (NetContext context = Fixture.CreateContext()) + { + string[] _ = + context.NetTestEntities + .Select(x => EF.Functions.Host(x.Inet)) + .ToArray(); + + AssertContainsSql("SELECT host(x.\"Inet\")"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void ValueTuple_cidr_Host() + { + using (NetContext context = Fixture.CreateContext()) + { + string[] _ = + context.NetTestEntities + .Select(x => EF.Functions.Host(x.Cidr)) + .ToArray(); + + AssertContainsSql("SELECT host(x.\"Cidr\")"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void IPAddress_inet_HostMask() + { + using (NetContext context = Fixture.CreateContext()) + { + IPAddress[] _ = + context.NetTestEntities + .Select(x => EF.Functions.HostMask(x.Inet)) + .ToArray(); + + AssertContainsSql("SELECT hostmask(x.\"Inet\")"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void ValueTuple_cidr_HostMask() + { + using (NetContext context = Fixture.CreateContext()) + { + IPAddress[] _ = + context.NetTestEntities + .Select(x => EF.Functions.HostMask(x.Cidr)) + .ToArray(); + + AssertContainsSql("SELECT hostmask(x.\"Cidr\")"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void IPAddress_inet_SubnetLength() + { + using (NetContext context = Fixture.CreateContext()) + { + int[] _ = + context.NetTestEntities + .Select(x => EF.Functions.SubnetLength(x.Inet)) + .ToArray(); + + AssertContainsSql("SELECT masklen(x.\"Inet\")"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void ValueTuple_cidr_SubnetLength() + { + using (NetContext context = Fixture.CreateContext()) + { + int[] _ = + context.NetTestEntities + .Select(x => EF.Functions.SubnetLength(x.Cidr)) + .ToArray(); + + AssertContainsSql("SELECT masklen(x.\"Cidr\")"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void IPAddress_inet_SubnetMask() + { + using (NetContext context = Fixture.CreateContext()) + { + IPAddress[] _ = + context.NetTestEntities + .Select(x => EF.Functions.SubnetMask(x.Inet)) + .ToArray(); + + AssertContainsSql("SELECT netmask(x.\"Inet\")"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void ValueTuple_cidr_SubnetMask() + { + using (NetContext context = Fixture.CreateContext()) + { + IPAddress[] _ = + context.NetTestEntities + .Select(x => EF.Functions.SubnetMask(x.Cidr)) + .ToArray(); + + AssertContainsSql("SELECT netmask(x.\"Cidr\")"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void IPAddress_inet_Network() + { + using (NetContext context = Fixture.CreateContext()) + { + (IPAddress Address, int Subnet)[] _ = + context.NetTestEntities + .Select(x => EF.Functions.Network(x.Inet)) + .ToArray(); + + AssertContainsSql("SELECT network(x.\"Inet\")"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void ValueTuple_cidr_Network() + { + using (NetContext context = Fixture.CreateContext()) + { + (IPAddress Address, int Subnet)[] _ = + context.NetTestEntities + .Select(x => EF.Functions.Network(x.Cidr)) + .ToArray(); + + AssertContainsSql("SELECT network(x.\"Cidr\")"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void IPAddress_inet_SetSubnetLength() + { + using (NetContext context = Fixture.CreateContext()) + { + IPAddress[] _ = + context.NetTestEntities + .Select(x => EF.Functions.SetSubnetLength(x.Inet, 0)) + .ToArray(); + + AssertContainsSql("SELECT set_masklen(x.\"Inet\", 0)"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void ValueTuple_cidr_SetSubnetLength() + { + using (NetContext context = Fixture.CreateContext()) + { + (IPAddress Address, int Subnet)[] _ = + context.NetTestEntities + .Select(x => EF.Functions.SetSubnetLength(x.Cidr, 0)) + .ToArray(); + + AssertContainsSql("SELECT set_masklen(x.\"Cidr\", 0)"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void IPAddress_inet_Text() + { + using (NetContext context = Fixture.CreateContext()) + { + string[] _ = + context.NetTestEntities + .Select(x => EF.Functions.Text(x.Inet)) + .ToArray(); + + AssertContainsSql("SELECT text(x.\"Inet\")"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void ValueTuple_cidr_Text() + { + using (NetContext context = Fixture.CreateContext()) + { + string[] _ = + context.NetTestEntities + .Select(x => EF.Functions.Text(x.Cidr)) + .ToArray(); + + AssertContainsSql("SELECT text(x.\"Cidr\")"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void IPAddress_inet_SameFamily() + { + using (NetContext context = Fixture.CreateContext()) + { + IPAddress inet = new IPAddress(0); + + bool[] _ = + context.NetTestEntities + .Select(x => EF.Functions.SameFamily(x.Inet, inet)) + .ToArray(); + + AssertContainsSql("SELECT inet_same_family(x.\"Inet\", @__inet_1)"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void ValueTuple_cidr_SameFamily() + { + using (NetContext context = Fixture.CreateContext()) + { + (IPAddress Address, int Subnet) cidr = (new IPAddress(0), 0); + + bool[] _ = + context.NetTestEntities + .Select(x => EF.Functions.SameFamily(x.Cidr, cidr)) + .ToArray(); + + AssertContainsSql("SELECT inet_same_family(x.\"Cidr\", @__cidr_1)"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void IPAddress_inet_Merge() + { + using (NetContext context = Fixture.CreateContext()) + { + IPAddress inet = new IPAddress(0); + + (IPAddress Address, int Subnet)[] _ = + context.NetTestEntities + .Select(x => EF.Functions.Merge(x.Inet, inet)) + .ToArray(); + + AssertContainsSql("SELECT inet_merge(x.\"Inet\", @__inet_1)"); + } + } + + /// + /// Tests translation for . + /// + [Fact] + public void ValueTuple_cidr_Merge() + { + using (NetContext context = Fixture.CreateContext()) + { + (IPAddress Address, int Subnet) cidr = (new IPAddress(0), 0); + + (IPAddress Address, int Subnet)[] _ = + context.NetTestEntities + .Select(x => EF.Functions.Merge(x.Cidr, cidr)) + .ToArray(); + + AssertContainsSql("SELECT inet_merge(x.\"Cidr\", @__cidr_1)"); + } + } + + #endregion + #region Fixtures /// @@ -308,7 +732,7 @@ public class NetTestEntity /// /// The network address. /// - public (IPAddress IPAddress, int Subnet) Cidr { get; set; } + public (IPAddress Address, int Subnet) Cidr { get; set; } } ///