【问题标题】:How assign EF table data to List如何将 EF 表数据分配给 List
【发布时间】:2019-10-18 04:58:41
【问题描述】:

我需要从表中获取特定的原始列值。我写代码如下,

public List<MessageTemplateDto> GetMessageTemplate(int tenantId,NotifyVia notifyVia,string notifyEvent)
{

    ClientContext context = clientContextFactory.GetContext(tenantId);
    List<MessageTemplateDto> msgTemplate = new List<MessageTemplateDto>();
    var xx = context.MessageTemplates.Where(m => m.NotifyEvent == notifyEvent && m.SendVia == notifyVia.ToString()).ToList();
    msgTemplate.Add(xx);
    return msgTemplate;
}

但上面的代码给出了这个错误,

cannot convert from 'System.Collections.Generic.List<Kronos.FMSI.LT.EFModel.ClientData.MessageTemplate>' to 'Kronos.FMSI.LT.Api.Interface.Models.Notification.MessageTemplateDto'

我的DTO类如下,

public class MessageTemplateDto
{
    public int TemplateID { get; set; }
    public string NotifyEvent { get; set; }
    public string SendVia { get; set; }
    public string Template { get; set; }
}

我在这里做错了什么?正如我之前提到的,我需要从原始值(Template 值)中获取一列值。我需要将返回类型写为 List&lt;MessageTemplateDto&gt; 吗?如果我使用返回类型作为字符串,这不是一个好习惯吗?

【问题讨论】:

    标签: c# list entity-framework model


    【解决方案1】:

    您必须使用 .Select() 创建一个新的 MessageTemplateDto 并设置您要填充的每个属性:

    return context.MessageTemplates
      .Where(m => m.NotifyEvent == notifyEvent && m.SendVia == notifyVia.ToString())
      .Select(r => new MessageTemplateDto() {
          TemplateID = r.WhateverTheColumnNameForIdIsInYourMapping,
          r.NotifyEvent //both column and dto property have same name so this can be simplified
          r.SendVia //again, both dto and column seem to have the same name so this can simply be this
          Template = r.WhateverYourColumnNameForTemplateIsInTheContext 
        }
      .ToList();
    

    等等

    在 select 中,r 代表上下文传递的表行,因此 r 中的列名将是您在映射中设置的任何内容。你没有显示映射,所以我不知道你的一些列名是什么

    这不是进行 throw 的唯一方法,您可以执行以下操作,例如在 Dto 中提供一个构造函数,该构造函数接受一个表示实体的类型的对象,然后在构造函数中设置属性。这通常很少这样做,因为它将您的 Dto 对象套件绑定为依赖于您的实体域,并且它们可能应该是分开的。您可以在运行此查询的存储库类中创建 Map 方法; map 接受一个 db 实体并返回一个 dto;这取决于您将执行多少次 - 如果这是您查询此表并创建模板 d 列表的唯一地方,那么为它创建映射方法是没有意义的。

    最终,最初的问题是您的原始查询返回了一个 db 实体对象列表,并且它们不能直接分配给声明为只有一个 dto 对象列表的列表,因为它们是不同的对象。就像将汽车类型对象列表分配给列表一样 - 您必须使用 Select 从数据实体生成 Dto。 Dto 通常是不同的、更轻的、更少的属性,可能是一些不在 db 中的计算属性(例如 dto 有 Age,db 有 bitthdaye)并且用于将少量数据移动到其他地方,甚至可能通过网络,因此它们为什么更小

    【讨论】:

    • 能否告诉我第二个问题的答案?我需要返回整个模型以获取一个值吗?我不能使用字符串作为返回类型吗?
    • 我把代码改成了你的答案,还是有同样的错误
    • 将代码更改为 this 并且错误消失了。 List&lt;MessageTemplateDto&gt; msgTemplate = context.MessageTemplates.Where(m =&gt; m.NotifyEvent == notifyEvent &amp;&amp; m.SendVia == notifyVia.ToString()).Select(r =&gt; new MessageTemplateDto() { Template = r.Template }).ToList();
    • 嗯,它本身还不错..如果你用其他东西填写它,那么你可以在需要表中的母亲数据的其他地方重用它——那会很好! :) 但是调用类已经知道 Via 和事件,所以如果它不关心模板 ID,那么确保你可以让它返回一个字符串列表。你仍然需要一个选择,但它看起来更像.Select(r=&gt;r.Template)
    • 取决于你想要哪个 :) 如果你想要第一个,那么它就是 messageTemplateDtos[0].Template - 像数组一样索引你的列表并拉出 .Template。检查您的列表甚至有第一个可能是明智的,因为它可能完全为空,在这种情况下您将获得索引超出范围异常
    猜你喜欢
    • 1970-01-01
    • 2016-04-18
    • 2016-05-20
    • 2016-03-24
    • 1970-01-01
    • 2012-06-21
    • 2016-05-11
    • 2012-07-12
    • 2013-02-05
    相关资源
    最近更新 更多