Sup*_*Bob 3 c# attributes dapper dapper-contrib
此资源解释了如何Computed排除属性(仅在更新中?)。
指定应从更新中排除该属性。
Run Code Online (Sandbox Code Playgroud)[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); }
不Write(false)达到同样的目的吗?[Computed]和 和有[Write(false)]什么区别?
编辑:
我刚刚检查了为回答我的问题而链接的资源。它几乎一针见血!有人可以确认这两个属性是否执行相同的操作,但只是以两种不同的方式表达,以便为用户提供更好的抽象?
双方[Computed]并Write(false)会忽略的财产,同时INSERT还有UPDATE操作。所以,两者都是一样的。您可以使用其中任何一种。
文档如下:
[Write(true/false)]- 此属性是(不可)写的[Computed]- 这个属性是计算出来的,不应该是更新的一部分
关于Write:
如上面文档中的第一行所述,Write处理“可写”行为。这应该包括INSERT和UPDATE。
这也可以在此处的源代码中确认:
Run Code Online (Sandbox Code Playgroud)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; }
关于Computed:
不过,上面文档中的第二行有点宽泛。
不应成为更新的一部分
这是否意味着它可以是 的一部分INSERT?不,不是的; 它还涵盖了这两个操作。这可以通过以下代码观察:
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 ''
)
Run Code Online (Sandbox Code Playgroud)
[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; }
}
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
使用上面的代码,您会发现无论您选择哪个属性来装饰该属性,都不会考虑 forINSERT或 for UPDATE。所以基本上,这两个属性都扮演着同样的角色。
这可以在 github 上的Dapper.Tests.Contrib测试项目中进一步确认。
Run Code Online (Sandbox Code Playgroud)[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" });
看上面代码中的注释和分配给属性的值,很明显Computed应该忽略该属性进行INSERT操作;这是测试的预期结果。
为什么为同一目的提供这两种方式尚不清楚。它会引起混乱。
以下是一些额外的参考:
我使用
[Computed]或[Write("False")]为此。这对您的场景不起作用吗?
很高兴我能帮助你。每一天都是上学日!我不确定为什么它们都存在,因为我认为它们在功能上是相同的。我倾向于使用
[Computed]只是因为它更容易打字。
我知道使用 Dapper.Contrib 我可以使用
Write和Computed属性在写操作期间忽略属性。但是,这将忽略插入和更新的属性。我需要一种方法来忽略更新的属性。我的建议是添加 2 个属性......也许命名Insertable(bool)和Updateable(bool). 当一个false值传递给这些时,框架将排除给定操作的该属性。这是一种解决非常常见问题的轻量级、直接的方法。
我认为Computed属性与计算列没有任何关系,因为 Dapper.Contrib 支持多个 RDBMS。