Both [Computed]
and Write(false)
will ignore the property while INSERT
as well as UPDATE
operations. So, both of them are same. You can use any one of it.
Documentation says below:
[Write(true/false)]
- this property is (not) writeable
[Computed]
- this property is computed and should not be part of updates
About Write
:
As stated in first line in document above, Write
handles "writeable" behavior. This should include both INSERT
and UPDATE
.
This can also be confirmed in source code here:
var properties = type.GetProperties().Where(IsWriteable).ToArray();
...
...
...
private static bool IsWriteable(PropertyInfo pi)
{
var attributes = pi.GetCustomAttributes(typeof(WriteAttribute), false).AsList();
if (attributes.Count != 1) return true;
var writeAttribute = (WriteAttribute)attributes[0];
return writeAttribute.Write;
}
About Computed
:
Second line in document above is bit broad though.
should not be part of updates
Does that mean it can be the part of INSERT
? No, it does not; it also cover both the actions. This can be observed with below code:
CREATE TABLE TestTable
(
[ID] [INT] IDENTITY (1,1) NOT NULL CONSTRAINT TestTable_P_KEY PRIMARY KEY,
[Name] [VARCHAR] (100) NOT NULL,
[ComputedCol] [VARCHAR] (100) NOT NULL DEFAULT '',
[NonWriteCol] [VARCHAR] (100) NOT NULL DEFAULT ''
)
[Table("TestTable")]
public class MyTable
{
[Key]
public int ID { get; set; }
public string Name { get; set; }
[Computed]
public string ComputedCol { get; set; }
[Write(false)]
public string NonWriteCol { get; set; }
}
int id;
using(SqlConnection conn = new SqlConnection(@"connection string"))
{
MyTable myTable = new MyTable();
myTable.Name = "Name";
myTable.ComputedCol = "computed";
myTable.NonWriteCol = "writable";
conn.Insert<MyTable>(myTable);
id = myTable.ID;
}
using(SqlConnection conn = new SqlConnection(@"connection string"))
{
MyTable myTable = conn.Get<MyTable>(id);
myTable.Name = "Name_1";
myTable.ComputedCol = "computed_1";
myTable.NonWriteCol = "writable_1";
conn.Update<MyTable>(myTable);
}
With above code, you will observe that no matter which attribute you choose to decorate the property, it will neither be considered for INSERT
nor for UPDATE
. So basically, both the attributes are playing same role.
This can be further confirmed in Dapper.Tests.Contrib test project on github.
[Table("Automobiles")]
public class Car
{
public int Id { get; set; }
public string Name { get; set; }
[Computed]
public string Computed { get; set; }
}
...
...
...
//insert with computed attribute that should be ignored
connection.Insert(new Car { Name = "Volvo", Computed = "this property should be ignored" });
Source: 1 and 2
Looking at the comment and the value assigned to the property in above code, it makes clear that Computed
should also ignore the property for INSERT
operation; it is expected result of the test.
Why those two ways are provided for same purpose is not known. It causes confusion.
Following are some additional references:
Comment 1
I use [Computed]
or [Write("False")]
for that. Does that not work for your scenario?
Comment 2
Glad I could help. Every day is a school day! I'm not sure why they both exist though as I think they are functionally the same. I tend to use [Computed]
just because it is marginally easier to type.
Comment 3
I understand that using Dapper.Contrib I can use the Write
and Computed
attributes to ignore properties during write operations. However, this will ignore the properties on both insert and update. I need a way to ignore properties on updates. My suggestion would be to add 2 attributes... perhaps named Insertable(bool)
and Updateable(bool)
. When a false
value is passed to these the framework would exclude that property for the given operation. This is a lightweight, straightforward approach to a very common problem.
I don't think Computed
attribute has anything to do with Computed Columns as Dapper.Contrib support multiple RDBMS.