Hi *,

this patch implements the correct (I hope) behaviour for the "Storage"
property of the "Column" attribute. If "Storage" is present the normal
set/get logic is skipped and the backing field is accessed directly
(even if private). This is the first half of the patch; the second half
will do more extensive changes to ColumnExpression (we're discussing
this in ##dblinq.)

I added a test currently marked "POSTGRES" only because I develop on
GNU/Linux with MonoDevelop and I can't modify the project files and be
sure they will still work in MS VS. For the test I added a custom
NorthwindCustom class in the PostgreSQL examples directory and a
CreateCustomDB() call to TestBase.cs (guarded by #if). The test itself
lives in ReadTest.

So I need some help after commiting the patch to:

1) Add the NorthwindCustom.cs file to the PostgreSQL tests project; and
2) Make the test available for other backends.

Ok to commit?

federico

-- 
Federico Di Gregorio                         http://people.initd.org/fog
Debian GNU/Linux Developer                                [email protected]
INIT.D Developer                                           [email protected]
                             Domani si vede domani. -- Alessandra O'Hara
Index: src/DbLinq/Data/Linq/Sugar/Implementation/ExpressionDispatcher.Registrar.cs
===================================================================
--- src/DbLinq/Data/Linq/Sugar/Implementation/ExpressionDispatcher.Registrar.cs	(revisione 1184)
+++ src/DbLinq/Data/Linq/Sugar/Implementation/ExpressionDispatcher.Registrar.cs	(copia locale)
@@ -382,14 +382,19 @@
                                                           BuilderContext builderContext)
         {
             var bindings = new List<MemberBinding>();
+            var row = builderContext.QueryContext.DataContext.Mapping.GetTable(tableExpression.Type).RowType;
+            
             foreach (var columnExpression in RegisterAllColumns(tableExpression, builderContext))
             {
-                PropertyInfo propertyInfo = columnExpression.MemberInfo as PropertyInfo;
+                var dataMember = row.GetDataMember(columnExpression.MemberInfo);
+                
+                MemberInfo memberInfo = dataMember.StorageMember ?? columnExpression.MemberInfo;
+                PropertyInfo propertyInfo = memberInfo as PropertyInfo;
                 if (propertyInfo == null || propertyInfo.CanWrite)
                 {
                     var parameterColumn = GetOutputValueReader(columnExpression,
                                                                dataRecordParameter, mappingContextParameter, builderContext);
-                    var binding = Expression.Bind(columnExpression.MemberInfo, parameterColumn);
+                    var binding = Expression.Bind(memberInfo, parameterColumn);
                     bindings.Add(binding);
                 }
             }
Index: src/DbLinq/Test/Providers/ReadTest.cs
===================================================================
--- src/DbLinq/Test/Providers/ReadTest.cs	(revisione 1184)
+++ src/DbLinq/Test/Providers/ReadTest.cs	(copia locale)
@@ -1028,5 +1028,19 @@
             var q = db.Customers.Where(c => c.ContactName == "'; DROP TABLE DoesNotExist; --");
             Assert.AreEqual(0, q.Count());
         }
+              
+#if POSTGRES
+        [Test]
+        public void NoStorage()
+        {
+            var db = CreateCustomDB();
+            var q = db.Categories.Where(c => c.CategoryID == 1);
+            var r = q.First();
+            Assert.AreEqual(1, q.Count());
+            Assert.AreEqual(1, r.CategoryID);
+            Assert.IsTrue(r.propertyInvoked_CategoryName);     
+            Assert.IsFalse(r.propertyInvoked_Description);     
+        }
+#endif    
     }
 }
Index: src/DbLinq/Test/Providers/TestBase.cs
===================================================================
--- src/DbLinq/Test/Providers/TestBase.cs	(revisione 1184)
+++ src/DbLinq/Test/Providers/TestBase.cs	(copia locale)
@@ -138,6 +138,23 @@
             return db;
         }
 
+#if POSTGRES
+        public NorthwindCustom CreateCustomDB()
+        {
+            return CreateCustomDB(System.Data.ConnectionState.Closed);
+        }
+
+        public NorthwindCustom CreateCustomDB(System.Data.ConnectionState state)
+        {
+            CheckRecreateSqlite();
+            var conn = CreateConnection(connStr);
+            if (state == System.Data.ConnectionState.Open)
+                conn.Open();
+            var db = new NorthwindCustom(conn) { Log = Console.Out };
+            return db;
+        }     
+#endif
+        
         /// <summary>
         /// execute a sql statement, return an Int64.
         /// </summary>
Index: examples/DbLinq.Pgsql.Example/nwind/NorthwindCustom.cs
===================================================================
--- examples/DbLinq.Pgsql.Example/nwind/NorthwindCustom.cs	(revisione 0)
+++ examples/DbLinq.Pgsql.Example/nwind/NorthwindCustom.cs	(revisione 0)
@@ -0,0 +1,69 @@
+using System;
+using System.Data;
+using System.Data.Linq.Mapping;
+using System.Diagnostics;
+using System.Reflection;
+using DbLinq.Data.Linq;
+using DbLinq.Vendor;
+
+namespace nwind
+{
+    public partial class NorthwindCustom : DataContext
+    {
+        public NorthwindCustom(IDbConnection connection)
+        : base(connection, new DbLinq.PostgreSql.PgsqlVendor())
+        {
+        }
+
+        public NorthwindCustom(IDbConnection connection, IVendor vendor)
+        : base(connection, vendor)
+        {
+        }
+
+        public Table<CategoryCustom> Categories { get { return GetTable<CategoryCustom>(); } }
+    }
+
+    [Table(Name = "public.\"Categories\"")]
+    public partial class CategoryCustom
+    {
+        public bool propertyInvoked_CategoryName = false;
+        public bool propertyInvoked_Description = false;
+        
+        // Tests the Storage without a setter for the property.
+        private int _categoryID;
+        [Column(Storage = "_categoryID", Name = "\"CategoryID\"", DbType = "integer(32,0)", IsPrimaryKey = true, IsDbGenerated = true, CanBeNull = false, Expression = "nextval('\"Categories_CategoryID_seq\"')")]
+        public int CategoryID {
+            get { return _categoryID; }
+        }
+
+        // No "Storage" attribute, this should go through the property.
+        private string _categoryName;
+        [Column(Name = "\"CategoryName\"", DbType = "character varying(15)", CanBeNull = false)]
+        public string CategoryName {
+            get { return _categoryName; }
+            set {
+                if (value != _categoryName)
+                {
+                    _categoryName = value;
+                }
+                propertyInvoked_CategoryName = true;
+            }
+        }
+
+        // "Storage" and property, should set the field directly.
+        private string _description;
+        [DebuggerNonUserCode]
+        [Column(Storage = "_description", Name = "\"Description\"", DbType = "text")]
+        public string Description {
+            get { return _description; }
+            set
+            {
+                if (value != _description)
+                {
+                    _description = value;
+                }
+                propertyInvoked_Description = true;
+            }
+        }
+    }
+}
\ No newline at end of file

Attachment: signature.asc
Description: Questa รจ una parte del messaggio firmata digitalmente

Reply via email to