[计算]和[写入(假)]属性有什么区别?

时间:2019-08-27 10:50:56

标签: c# attributes dapper dapper-contrib

This资源介绍了wait_for如何排除属性(仅在更新中?)。

  

指定该属性应从更新中排除。

Computed

[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]有什么区别?

编辑:

我刚刚回答了问题,已经检查了资源linked。差一点就钉上了!有人可以确认两个属性是否都执行相同的操作,但只是用两种不同的方式措辞,以便为用户提供更好的抽象?

1 个答案:

答案 0 :(得分:1)

[Computed]Write(false)INSERTUPDATE操作时都将忽略该属性。因此,它们都是相同的。您可以使用任何一种。

Documentation如下:

  
      
  • [Write(true/false)]-此属性(不可)写入
  •   
  • [Computed]-此属性是计算得出的,不应作为更新的一部分
  •   

关于Write

如上面文档第一行所述,Write处理“可写”行为。这应该同时包含INSERTUPDATE

这也可以在源代码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;
}

关于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 ''
)
[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);
}

使用上面的代码,您将发现无论选择哪个属性来装饰属性,INSERTUPDATE都不会考虑它。因此,基本上,这两个属性都扮演着相同的角色。

可以在github上的Dapper.Tests.Contrib测试项目中进一步确认。

[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" });
     

来源:12

通过查看上面代码中的注释和分配给该属性的值,可以清楚地看出Computed也应该忽略INSERT操作的属性;这是测试的预期结果。

为何出于相同目的提供这两种方式尚不清楚。会引起混乱。

以下是一些其他参考:

Comment 1

  

为此,我使用[Computed][Write("False")]。这不适用于您的情况吗?

Comment 2

  

很高兴我可以帮忙。每天都是上学日!我不确定它们为什么同时存在,因为我认为它们在功能上是相同的。我倾向于使用[Computed]只是因为它稍微容易键入。

Comment 3

  

我了解使用Dapper.Contrib可以使用WriteComputed属性在写操作期间忽略属性。但是,这将忽略插入和更新的属性。我需要一种忽略更新属性的方法。我的建议是添加2个属性……可能分别命名为Insertable(bool)Updateable(bool)。当false值传递给这些值时,框架将排除给定操作的该属性。这是解决常见问题的一种轻巧,直接的方法。

作为Dapper,我不认为Computed属性与Computed Columns有任何关系。Contrib支持多个RDBMS。