[Computed] 和 [Write(false)] 属性有什么区别? [英] What's the difference between [Computed] and [Write(false)] attributes?

查看:35
本文介绍了[Computed] 和 [Write(false)] 属性有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

资源解释了 Computed 如何排除属性(仅在更新中?).

<块引用>

指定属性应从更新中排除.

[Table("Invoice")]公共类 InvoiceContrib{[钥匙]公共 int InvoiceID { 获取;放;}公共字符串代码 { 获取;放;}public InvoiceKind Kind {获取;放;}[写(假)][计算]公共字符串 FakeProperty { 获取;放;}}使用 (var connection = My.ConnectionFactory()){连接.打开();var invoices = connection.GetAll().ToList();//FakeProperty 被跳过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 处理可写"行为.这应该包括 INSERTUPDATE.

这也可以在源代码中确认这里:

<块引用>

var 属性 = type.GetProperties().Where(IsWriteable).ToArray();.........私有静态布尔 IsWriteable(PropertyInfo pi){var 属性 = pi.GetCustomAttributes(typeof(WriteAttribute), false).AsList();if (attributes.Count != 1) 返回真;var writeAttribute = (WriteAttribute)attributes[0];返回 writeAttribute.Write;}

关于计算:

上面文档的第二行有点宽泛.

<块引用>

不应成为更新的一部分

这是否意味着它可以成为 INSERT 的一部分?不,不是的;它还涵盖了这两个动作.这可以通过以下代码观察到:

创建表测试表([ID] [INT] IDENTITY (1,1) NOT NULL 约束 TestTable_P_KEY 主键,[名称] [VARCHAR] (100) 非空,[ComputedCol] [VARCHAR] (100) NOT NULL DEFAULT '',[NonWriteCol] [VARCHAR] (100) NOT NULL DEFAULT '')

[Table("TestTable")]公共课 MyTable{[钥匙]公共 int ID { 获取;放;}公共字符串名称 { 获取;放;}[计算]公共字符串 ComputedCol { 获取;放;}[写(假)]公共字符串 NonWriteCol { 获取;放;}}

int id;using(SqlConnection conn = new SqlConnection(@"连接字符串")){我的表我的表 = 新的我的表();myTable.Name = "名称";myTable.ComputedCol = "计算";myTable.NonWriteCol = "可写";conn.Insert<MyTable>(myTable);id = myTable.ID;}using(SqlConnection conn = new SqlConnection(@"连接字符串")){MyTable myTable = conn.Get(id);myTable.Name = "Name_1";myTable.ComputedCol = "computed_1";myTable.NonWriteCol = "可写_1";conn.Update(myTable);}

通过上面的代码,你会发现无论你选择哪个属性来装饰属性,INSERTUPDATE都不会考虑它.所以基本上,这两个属性都扮演着同样的角色.

这可以在 Dapper.Tests.Contrib github上的测试项目.

<块引用>

[Table("Automobiles")]公共级汽车{公共 int ID { 获取;放;}公共字符串名称 { 获取;放;}[计算]公共字符串计算{得到;放;}}.........//插入应该被忽略的计算属性connection.Insert(new Car { Name = "Volvo", Computed = "这个属性应该被忽略" });

来源:12

查看上面代码中的注释和分配给属性的值,很明显Computed也应该忽略INSERT操作的属性;这是预期的测试结果.

为什么提供这两种方式用于相同目的尚不清楚.它会引起混乱.

以下是一些额外的参考资料:

评论1

<块引用>

我为此使用 [Computed][Write("False")].这不适用于您的方案吗?

评论2

<块引用>

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

评论3

<块引用>

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

我认为 Computed 属性与 计算列作为 Dapper.Contrib 支持多个 RDBMS.

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?

解决方案

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.

这篇关于[Computed] 和 [Write(false)] 属性有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆