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
signature.asc
Description: Questa รจ una parte del messaggio firmata digitalmente
