Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>As you said, the only way is to fetch the original object and update its properties. </p> <p>You could implement a generic extension to Data.Linq.Table which accepts your model bound object an retrieves the original item from the DataContext by its primary key. After this you iterate thru all properties with refrection and set the new values to the retrieved entity. You may give an array of properties you wish to update in case not all properties were bound thru model binding and so set to default.</p> <p>I know Refelction is not a good solution, but it helps sometimes.</p> <pre><code>public static class TableExtensions { public static void UpdateOnSubmit&lt;T&gt;(this Table&lt;T&gt; table, T changes) where T : class { UpdateOnSubmit(table, changes, null); } public static void UpdateOnSubmit&lt;T&gt;(this Table&lt;T&gt; table, T changes, string[] properties) where T : class { var item = table.FirstOrDefault(GetPkExpression(table, changes)); if (item != null) { UpdateItem&lt;T&gt;(ref item, changes, properties); } } private static void UpdateItem&lt;T&gt;(ref T original, T changes, string[] properties) where T : class { Type OriginalType = typeof(T); if (properties == null) { PropertyInfo[] Info = OriginalType.GetProperties(); foreach (PropertyInfo PI in Info) { if (IsUpdateableColumn(PI)) { PI.SetValue(original, PI.GetValue(changes, null), null); } } } else { foreach (string propName in properties) { PropertyInfo PI = OriginalType.GetProperty(propName); if (PI != null &amp;&amp; IsUpdateableColumn(PI)) { PI.SetValue(original, PI.GetValue(changes, null), null); } } } } private static bool IsUpdateableColumn(PropertyInfo pi) { object[] attributes = pi.GetCustomAttributes(typeof(ColumnAttribute), true); if (attributes.Length == 0) return false; foreach (ColumnAttribute attr in attributes) { if (attr.IsDbGenerated) return false; } return true; } private static Expression&lt;Func&lt;T, bool&gt;&gt; GetPkExpression&lt;T&gt;(Table&lt;T&gt; table, T value) where T : class { var mapping = table.Context.Mapping.GetTable(typeof(T)); var pk = mapping.RowType.DataMembers.FirstOrDefault(d =&gt; d.IsPrimaryKey); if (pk == null) { throw new Exception(string.Format("Table {0} does not contain a Primary Key field", mapping.TableName)); } var pkValue = typeof(T).GetProperty(pk.Name).GetValue(value, null); var param = Expression.Parameter(typeof(T), "e"); return Expression.Lambda&lt;Func&lt;T, bool&gt;&gt;(Expression.Equal(Expression.Property(param, pk.Name), Expression.Constant(pkValue)), new ParameterExpression[] { param }); } } </code></pre> <p>After using this extension your Update function should look like:</p> <pre><code>public void Update(UserHour userHour) { CRMDataContext c = new CRMDataContext(); c.UserHour.UpdateOnSubmit(userHour, new string[] { "Id", "Duration", "HourCategoryId", "Explanation", "InvoiceTypeId", "StartDate", "StartTime", "TicketId" }); c.SubmitChanges(); } </code></pre> <p>You may omit the array with property names if all properties sould be updated.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload