EF和Automapper

时间:2017-10-03 13:40:06

标签: c# entity-framework entity-framework-6 automapper

我有以下域类:

public class ApplicationDriverLicenseDomain
{
    public ApplicationDriverLicenseDomain()
    {
        CDLTypes = new List<ApplicationLicenseCDLTypeDomain>();
        Endorsements = new List<ApplicationLicenseEndorsementDomain>();
    }

    public string Name { get; set; }
    public string MaidenName { get; set; }

    public virtual List<ApplicationLicenseCDLTypeDomain> CDLTypes { get; set; }

    public virtual List<ApplicationLicenseEndorsementDomain> Endorsements { get; set; }
}

public class ApplicationLicenseCDLTypeDomain
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class ApplicationLicenseEndorsementDomain
{
    public int Id { get; set; }
    public string Name { get; set; }
}

和EF课程:

[Table("ApplicationLicenseCDLTypes")]
public partial class ApplicationLicenseCDLType
{
    public ApplicationLicenseCDLType()
    {
        ApplicationDriverLicenses = new HashSet<ApplicationDriverLicense>();
    }

    public int Id { get; set; }
    [Required]
    [StringLength(256)]
    public string Name { get; set; }

    public virtual ICollection<ApplicationDriverLicense> ApplicationDriverLicenses { get; set; }

}

[Table("ApplicationLicenseEndorsements")]
public partial class ApplicationLicenseEndorsement
{
    public ApplicationLicenseEndorsement()
    {
        ApplicationDriverLicenses = new HashSet<ApplicationDriverLicense>();
    }

    public int Id { get; set; }
    [Required]
    [StringLength(256)]
    public string Name { get; set; }

    public virtual ICollection<ApplicationDriverLicense> ApplicationDriverLicenses { get; set; }

}

[Table("ApplicationDriverLicenses")]
public partial class ApplicationDriverLicense
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public ApplicationDriverLicense()
    {
        CDLTypes = new HashSet<ApplicationLicenseCDLType>();
        Endorsements = new HashSet<ApplicationLicenseEndorsement>();
    }

    [Required]
    [StringLength(256)]
    public string Name { get; set; }

    [Key, ForeignKey("Driver")]
    public int DriverId { get; set; }
    public virtual ApplicationDriver Driver { get; set; }


    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<ApplicationLicenseCDLType> CDLTypes { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<ApplicationLicenseEndorsement> Endorsements { get; set; }

}

此外,还有2个附加表来存储选定的CDLTypes / Endorsements

        modelBuilder.Entity<ApplicationDriverLicense>()
            .HasMany(e => e.CDLTypes)
            .WithMany(e => e.ApplicationDriverLicenses)
            .Map(m => m.ToTable("ApplicationDriverLicenseCDLTypes").MapLeftKey("DriverId").MapRightKey("TypeId"));


        modelBuilder.Entity<ApplicationDriverLicense>()
            .HasMany(e => e.Endorsements)
            .WithMany(e => e.ApplicationDriverLicenses)
            .Map(m => m.ToTable("ApplicationDriverLicenseEndorsements").MapLeftKey("DriverId").MapRightKey("TypeId"));

然后我将域类映射到EF类:

        CreateMap<ApplicationDriverLicenseDomain, Infrastructure.Asset.ApplicationDriverLicense>();
        CreateMap<ApplicationLicenseEndorsementDomain, Infrastructure.Asset.ApplicationLicenseEndorsement>();
        CreateMap<ApplicationLicenseCDLTypeDomain, Infrastructure.Asset.ApplicationLicenseCDLType>();

但是当我尝试向DB添加记录时:

    public async Task AddApplicationAsync(ApplicationDriverDomain model)
    {
        Infrastructure.Asset.ApplicationDriver driver = mapper.Map<Infrastructure.Asset.ApplicationDriver>(model);
        db.ApplicationDrivers.Add(driver);
        await db.SaveChangesAsync();
    }

它为CDL类型/背书添加了新记录,而不是获取最新记录。据我了解,我应该做&#34;附加&#34;。如何使用Automapper规则?

2 个答案:

答案 0 :(得分:1)

虽然我同意上面的@DiskJunky评论,但是要解决手头的问题:在ApplicationDriverLicense课程中,您拥有EndorsementsCDLTypes类型的虚拟属性。 Auto-mapper正在填充这些属性,由于它们未附加到上下文,因此EF会为它们创建新记录。

我建议让Auto-Mapper Ignore映射这些虚拟属性,并将它们留空,这应该可以解决您的问题。

答案 1 :(得分:0)

我顺便实施了它:

    public async Task AddApplicationAsync(ApplicationDriverDomain model)
    {
        Infrastructure.Asset.ApplicationDriver driver = mapper.Map<Infrastructure.Asset.ApplicationDriver>(model);

        var cdlTypes = driver.CommercialLicense.CDLTypes;
        foreach (var type in cdlTypes)
        {
            db.ApplicationLicenseCDLTypes.Attach(type);
        }

        var endorsements = driver.CommercialLicense.Endorsements;
        foreach (var endorsement in endorsements)
        {
            db.ApplicationLicenseEndorsements.Attach(endorsement);
        }

        db.ApplicationDrivers.Add(driver);
        await db.SaveChangesAsync();
    }

所以,我没有达到我在一个地方描述所有规则的目的......:)