忽略模型属性上的属性。

29
我该如何使用dapper/dapper扩展/dapper rainbow等dapper库忽略我的模型属性?

对于Insert<Person>(person),person具有一种计算属性,该属性不属于数据库。 - Elisabeth
1
由于以下回答都没有提供适用于基于Dapper.Rainbow的项目的解决方案,因此我在此添加评论。Dapper Rainbow具有可用的IgnoreProperty属性。您的POCO类必须引用Dapper.Rainbow.{SQL},然后您可以使用[IgnoreProperty(true)]来排除要排除的属性。 - Vishnoo Rath
与Dapper.Contrib相关:https://dev59.com/PLXna4cB1Zd3GeqPTfUN - Amit Joshi
5个回答

31

Dapper.Contrib内置了支持将列标记为计算列的功能:添加ComputedAttribute以允许在插入时支持计算列。以下是它的工作原理:

class MyModel
{
  public string Property1 { get; set; }

  [Computed]
  public int ComputedProperty { get; set; }
}

标有Computed属性的属性将在插入时被忽略。

Translated:
The properties marked with the Computed attribute will be ignored during insertion.

还有一个[Write(false)]属性。有人能告诉我[Computed][Write(false)]之间的区别吗? - vaheeds
2
@vaheeds 我的最佳猜测是它们是由不同的人在不同的时间添加的,这些人可能不知道其他属性。我当时添加了“Computed”属性,并不知道任何“Write”属性。 - Ben Collins
6
在我看来,它们的意思不同 - [Computed] 的意思是“此列存在于数据库中,但是是计算列”,而 [Write(false)] 的意思是“此列不存在于数据库中”。 - stuartd
关于 [Write(false)][Computed] 的详细信息,请参考这个问题。 - Amit Joshi

17

Dapper的创建者Sam Saffron已回答了另一个SO用户的问题,您可以在这里查看。

此外,如果您想使用Sam在答案中提到的Dapper Extensions库,您可以从Github或Nuget获取它。

下面是一个忽略库中属性的示例测试项目

using System;
using System.Collections.Generic;
using DapperExtensions.Mapper;

namespace DapperExtensions.Test.Data
{
    public class Person
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime DateCreated { get; set; }
        public bool Active { get; set; }
        public IEnumerable<Phone> Phones { get; private set; }
    }

    public class Phone
    {
        public int Id { get; set; }
        public string Value { get; set; }
    }

    public class PersonMapper : ClassMapper<Person>
    {
        public PersonMapper()
        {
            Table("Person");
            Map(m => m.Phones).Ignore();
            AutoMap();
        }
    }
}

2
你在哪里/何时实例化PersonMapper类?Dapper扩展是否通过获取实体名称+“Mapper”字符串并尝试实例化它来查找Mapper类? - Elisabeth
2
是的,我相信Dapper Extensions的AutoMapper功能会寻找以单数实体名称+“Mapper”后缀的类来自动映射要忽略的字段、具有不同名称的字段等。换句话说,我认为(尚未尝试过),您只需定义这个PersonMapper类并从POCO中忽略您想要忽略的字段即可。请参阅此处的文档:https://github.com/tmsmith/Dapper-Extensions/wiki/AutoClassMapper - Shiva
好的,它对我起作用了。我的XXXMapper类具有相同的命名空间。 - Elisabeth

11
在我的案例中,我使用了Dapper.Contrib
在任何属性上使用[Write(false)]特性应该可以解决这个问题。 有些人建议使用[Computed]特性。
public class Person
{        
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }

    [Write(false)]
    public IEnumerable<Email> Emails { get; }
}

5

对于不想包含DapperExtensions的人来说,也可以使用标准的System.ComponentModel.DataAnnotations.Schema中的DatabaseGenerated

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]

2
此解决方案不适用于 Dapper 1.50.2,且不支持 .NET CORE。 - Gilberto Alexandre
在Dapper.Contrib中,插入/更新操作无法正常工作。 - Raman Zhylich
使用标准注释而不是自定义属性应该是Dapper.Contrib的首选选择。 - Jamie Pearcey

5
您可以设计一个不包含计算属性的基类,并将其用于插入操作。
  class BasePerson
    {
      public String Name {get;set;}
    }

    class Person: BasePerson
    {
     public String ComputedProperty {get;set;}
    }

    Insert<BasePerson>(person);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接