我正在尝试使用ExpressMapper将数据实体映射到模型。

如果我直接将实体映射到模型(它们都具有相同的属性),那么它工作正常。

但是,如果我将链接的实体映射到模型,则会出现错误



数据库结构:

c# - ExpressMapper/EntityFramework-没有为此对象定义无参数构造函数-LMLPHP

ExpressMapper注册:

Mapper.Register<DiscountDaysOfWeek, DiscountDaysOfWeekModel>()
      .Member(dest => dest.DiscountDayId, src => src.DiscountDayId)
      .Member(dest => dest.DiscountDaysOfWeekId, src => src.DiscountDaysOfWeekId)
      .Member(dest => dest.DiscountId, src => src.DiscountId)
      .Member(dest => dest.Discountday, src => src.DiscountDay.Day);

像这样调用:
var disDays = discs.SelectMany(x => x.DiscountDaysOfWeeks)
                   .Map<IQueryable<DiscountDaysOfWeek>, IQueryable<DiscountDaysOfWeekModel>>();

在调用时获取错误消息。

DiscountDaysOfWeekModel:
public class DiscountDaysOfWeekModel
{
    public int DiscountDaysOfWeekId { get; set; }
    public int DiscountId { get; set; }
    public int DiscountDayId { get; set; }
    public string Discountday { get; set; }
}

DiscountDayOfWeek(由EF生成)
public partial class DiscountDaysOfWeek
{
    public int DiscountDaysOfWeekId { get; set; }
    public int DiscountId { get; set; }
    public int DiscountDayId { get; set; }

    public virtual DiscountDay DiscountDay { get; set; }
    public virtual Discount Discount { get; set; }
}

DiscountDay(由EF生成):
public partial class DiscountDay
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public DiscountDay()
    {
        this.DiscountDaysOfWeeks = new HashSet<DiscountDaysOfWeek>();
    }

    public int DiscountDayId { get; set; }
    public string Day { get; set; }

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

样例工作一:在以下样例中,模型和实体具有相同的属性
Mapper.Register<DiscountPreventedPriceEnding, DiscountPreventedPriceEndingModel>();

var execPriceEndings = discs.SelectMany(x => x.DiscountPreventedPriceEndings)
                            .Map<IQueryable<DiscountPreventedPriceEnding>, IQueryable<DiscountPreventedPriceEndingModel>>();

任何帮助将不胜感激。

最佳答案

我很欣赏这是一个非常老的问题,但是鉴于我仅花了4个小时在ExpressMapper上调试了类似的There was an error: System.MissingMethodException: No parameterless constructor defined for this object错误,我认为我会对自己的发现有所了解。

因此,我们遇到了与您类似的情况,因为我们拥有类似这样的领域模型(以下均为简化示例):

public class Owner
{
    public int? ID { get; set; }
    public string Name { get; set; }
}

public class Animal
{
    public int? ID { get; set; }
    public string Name { get; set; }
    public int? OwnerID { get; set; }
    [ForeignKey("OwnerID")]
    public Owner Owner { get; set; }
}

使用以下 View 模型(即我们的API发送和接收的API):
public class AnimalViewModel
{
    public int? ID { get; set; }
    public string Name { get; set; }
    public string Owner { get; set; }
}

使用这样的映射:
Mapper.Register<Animal, AnimalViewModel>();
Mapper.Register<AnimalViewModel, Animal>();

在映射到域模型和 View 模型或从域模型和 View 模型映射时,我们将获得MissingMethodException,尽管 View 模型和域模型都具有公共(public)的默认构造函数。解决方案是在域模型中手动映射相关实体,并将其从ExpressMapper的映射中排除,如下所示:
Mapper.Register<Animal, AnimalViewModel>()
    .Ignore(a => a.Owner);
Mapper.Register<AnimalViewModel, Animal>()
    .Ignore(a => a.Owner);

通过阅读EntityMapper的源代码,看来MissingMethodException是完全红色的鲱鱼,与实际问题无关。实际的问题似乎是它无法弄清楚如何将一种类型转换为另一种类型。在我们的案例中-复杂的对象如上所述被映射到原语/从原语映射到-从映射器中排除相关对象并手动完成就足够了。

编辑:

经过进一步调查,我们将问题的根源追溯到以下事实:EF代理创建会创建生成的类型(例如,“MyModel_14289012”),该类型与在映射器中注册的类型不匹配。为防止这种情况,请将以下内容应用于您的上下文:
Context.Configuration.LazyLoadingEnabled = false;
Context.Configuration.ProxyCreationEnabled = false;

并手动包括模型中所需的任何嵌套/相关对象,如下所示:
Context.Animals
    .Include(a => a.Owner);

这将获取相关实体,但将其获取为实际类型,而不是EF生成的类型。

关于c# - ExpressMapper/EntityFramework-没有为此对象定义无参数构造函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37996111/

10-12 12:42