diff --git a/QueryBuilder.Tests/UpdateTests.cs b/QueryBuilder.Tests/UpdateTests.cs index ca553d08..7f96d013 100644 --- a/QueryBuilder.Tests/UpdateTests.cs +++ b/QueryBuilder.Tests/UpdateTests.cs @@ -118,5 +118,48 @@ public void UpdateWithIgnoreAndColumnProperties() c[EngineCodes.Firebird]); } + + + private class OrderProductComposite + { + public OrderProductComposite(string orderid, string productid, int quantity) + { + OrderId = orderid; + ProductId = productid; + Quantity = quantity; + Foo = "baz"; + } + + [Key("OrdId")] + public string OrderId { get; set; } + + [Key] + public string ProductId { get; set; } + + public int Quantity { get; set; } + + [Column("Faa")] + public string Foo { get; set; } + } + + [Fact] + public void UpdateWithKeyAttribute() + { + var order = new OrderProductComposite("ORD01", "PROD02", 20); + + var query = new Query("OrderProductComposite").AsUpdate(order); + + var c = Compile(query); + + + Assert.Equal( + "UPDATE [OrderProductComposite] SET [OrdId] = 'ORD01', [ProductId] = 'PROD02', [Quantity] = 20, [Faa] = 'baz' WHERE [OrdId] = 'ORD01' AND [ProductId] = 'PROD02'", + c[EngineCodes.SqlServer]); + + Assert.Equal( + "UPDATE \"ORDERPRODUCTCOMPOSITE\" SET \"ORDID\" = 'ORD01', \"PRODUCTID\" = 'PROD02', \"QUANTITY\" = 20, \"FAA\" = 'baz' WHERE \"ORDID\" = 'ORD01' AND \"PRODUCTID\" = 'PROD02'", + c[EngineCodes.Firebird]); + } + } } \ No newline at end of file diff --git a/QueryBuilder/ColumnAttribute.cs b/QueryBuilder/ColumnAttribute.cs index 88539923..3ef71b83 100644 --- a/QueryBuilder/ColumnAttribute.cs +++ b/QueryBuilder/ColumnAttribute.cs @@ -18,4 +18,18 @@ public ColumnAttribute(string name) } } + + + /// + /// This class is used as metadata on a property to determine if it is a primary key + /// + public class KeyAttribute : ColumnAttribute + { + public KeyAttribute([System.Runtime.CompilerServices.CallerMemberName] string name = "") + : base(name) + { + + } + + } } diff --git a/QueryBuilder/Query.Insert.cs b/QueryBuilder/Query.Insert.cs index f0696217..f08e8ab9 100644 --- a/QueryBuilder/Query.Insert.cs +++ b/QueryBuilder/Query.Insert.cs @@ -9,26 +9,34 @@ public partial class Query { public Query AsInsert(object data, bool returnId = false) { - var dictionary = new Dictionary(); + var dictionary = BuildDictionaryOnInsert(data); + + return AsInsert(dictionary, returnId); + } - var props = data.GetType() - .GetRuntimeProperties() - .Where(_ => _.GetCustomAttribute(typeof(IgnoreAttribute)) == null); - foreach (var item in props) + private Dictionary BuildDictionaryOnInsert(object data) + { + + var dictionary = new Dictionary(); + var props = data.GetType().GetRuntimeProperties(); + + foreach (PropertyInfo property in props) { - var attr = item.GetCustomAttribute(typeof(ColumnAttribute)) as ColumnAttribute; - if (attr != null) - { - dictionary.Add(attr.Name, item.GetValue(data)); - } - else + if (property.GetCustomAttribute(typeof(IgnoreAttribute)) != null) { - dictionary.Add(item.Name, item.GetValue(data)); + continue; } + + var value = property.GetValue(data); + + var colAttr = property.GetCustomAttribute(typeof(ColumnAttribute)) as ColumnAttribute; + var name = colAttr?.Name ?? property.Name; + + dictionary.Add(name, value); } - return AsInsert(dictionary, returnId); + return dictionary; } public Query AsInsert(IEnumerable columns, IEnumerable values) diff --git a/QueryBuilder/Query.Update.cs b/QueryBuilder/Query.Update.cs index b1c87c52..95653f8a 100644 --- a/QueryBuilder/Query.Update.cs +++ b/QueryBuilder/Query.Update.cs @@ -5,30 +5,47 @@ namespace SqlKata { + public partial class Query { public Query AsUpdate(object data) { - var dictionary = new Dictionary(); + var dictionary = BuildDictionaryOnUpdate(data); + return AsUpdate(dictionary); + } - var props = data.GetType().GetRuntimeProperties() - .Where(_ => _.GetCustomAttribute(typeof(IgnoreAttribute)) == null); - foreach (var item in props) + private static Dictionary> CacheDictionaryProperties = new Dictionary>(); + + + private Dictionary BuildDictionaryOnUpdate(object data) + { + + var dictionary = new Dictionary(); + var props = data.GetType().GetRuntimeProperties(); + + foreach (PropertyInfo property in props) { - var attr = item.GetCustomAttribute(typeof(ColumnAttribute)) as ColumnAttribute; - if (attr != null) - { - dictionary.Add(attr.Name, item.GetValue(data)); + if (property.GetCustomAttribute(typeof(IgnoreAttribute)) != null){ + continue; } - else + + var value = property.GetValue(data); + + var colAttr = property.GetCustomAttribute(typeof(ColumnAttribute)) as ColumnAttribute; + var name = colAttr?.Name ?? property.Name; + if(colAttr != null) { - dictionary.Add(item.Name, item.GetValue(data)); - } + if((colAttr as KeyAttribute) != null) + { + this.Where(name, value); + } + } + dictionary.Add(name, value); } - return AsUpdate(dictionary); + return dictionary; } public Query AsUpdate(IEnumerable columns, IEnumerable values)