问题
This resource explains how Computed
excludes a property (in an update only?).
Specifie the property should be excluded from update.
[Table("Invoice")] public class InvoiceContrib { [Key] public int InvoiceID { get; set; } public string Code { get; set; } public InvoiceKind Kind { get; set; } [Write(false)] [Computed] public string FakeProperty { get; set; } } using (var connection = My.ConnectionFactory()) { connection.Open(); var invoices = connection.GetAll<InvoiceContrib>().ToList(); // The FakeProperty is skipped invoices.ForEach(x => x.FakeProperty += "z"); var isSuccess = connection.Update(invoices); }
Doesn't Write(false)
fulfill the same purpose though? What's the difference between [Computed]
and [Write(false)]
?
Edit:
I've just checked the resource linked in response to my question. It almost hits the nail on this! Could someone please confirm if both attributes perform the same operations, but are just worded in two different ways, as to give a better abstraction to their users?
回答1:
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
andComputed
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 namedInsertable(bool)
andUpdateable(bool)
. When afalse
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.
来源:https://stackoverflow.com/questions/57673107/whats-the-difference-between-computed-and-writefalse-attributes