首页 > 解决方案 > 我无法在 c#asp.net MVC 中将 StringBuilder 转换为字符串

问题描述

我的发票类有一个StringBuilder属性,因此如果进行了调整,用户会添加注释作为调整原因的详细信息。此属性在创建时设置为新的空StringBuilder。只有在编辑模式下才会被.Append()添加。据我了解,这比adjustmentNotes += newAdjustmentNotes每次添加新笔记时都更有效。

我的 Invoice.cs 类如下。

public class Invoice
{
    [Key]
    public int InvoiceID { get; set; }

    [ForeignKey(nameof(Customer))]
    public int CustomerID { get; set; }
    public virtual Customer Customer { get; set; }

    public virtual ICollection<Job> Jobs { get; set; }
    public double  InvoiceAmount { get; set; }
    public StringBuilder AdjustmentNotes { get; set; }
    public bool Paid { get; set; }
}

在填充我的列表或详细信息视图时,我按如下方式查询数据库:

using (var ctx = new ApplicationDbContext())
{
    var query = ctx.Invoices
                   .Where(e => e.InvoiceID >= 0)
                   .Select(e => new InvoiceListItem
                                    {
                                         InvoiceID = e.InvoiceID,
                                         CustomerID = e.CustomerID,
                                         InvoiceAmount = e.InvoiceAmount,
                                         Paid = e.Paid,
                                         AdjustmentNotes = e.AdjustmentNotes.ToString()
                                    });
    return query.ToArray();
}

然后我收到以下错误消息。

System.NotSupportedException:“'StringBuilder' 类型的值无法转换为字符串。”

但根据 Microsoft 文档、此论坛上的其他问题以及各种资源,这是完成此任务的正确方法。

我当然可以将它改回字符串并根据需要使用 += 。这个特定属性不会有太多注释,但是有人可以解释我做错了什么吗?太感谢了!

编辑:为澄清起见,这是我的InvoiceListItem模型类:

public class InvoiceListItem
{
    public int InvoiceID { get; set; }
    public int CustomerID { get; set; }
    
    public  List<int> JobIDs { get; set; }
    public double InvoiceAmount { get; set; }

    [UIHint("Bool")]
    public bool Paid { get; set; }
    public string AdjustmentNotes { get; set; }
}

标签: c#asp.net-mvcentity-frameworklinqrazor

解决方案


EF Core 在错误消息中说:

我不知道如何转换StringBuilder.ToString()为目标数据库语言。

解决方案是在查询后进行转换:

var result = ctx.Invoices
    .Where(e => e.InvoiceID >= 0)
    .ToList() // First execute the query
    .Select( // Second convert Invoice to InvoiceListItem
        e => new InvoiceListItem {
            InvoiceID = e.InvoiceID,
            CustomerID = e.CustomerID,
            InvoiceAmount = e.InvoiceAmount,
            Paid = e.Paid,
            AdjustmentNotes = e.AdjustmentNotes.ToString()
        }
    );

如果要限制查询中返回的属性,可以使用中间类型,例如:

var query = ctx.Invoices
    .Where(e => e.InvoiceID >= 0)
    .Select(
        e => new {
            e.InvoiceID,
            e.CustomerID,
            e.InvoiceAmount,
            e.Paid,
            AdjustmentNotes
        }
    );
var result = query.ToList().
    .Select(
        e => new InvoiceListItem {
            InvoiceID = e.InvoiceID,
            CustomerID = e.CustomerID,
            InvoiceAmount = e.InvoiceAmount,
            Paid = e.Paid,
            AdjustmentNotes = e.AdjustmentNotes.ToString()
        }
    );

PS:我没有找到有关 EF Core 支持StringBuilder类型的信息,但是您的上下文模型是成功构建的,然后 EF Core 似乎支持StringBuilder类型...

如果有支持,它似乎非常有限(请参阅您问题中的错误)。也许您可以考虑使用String而不是StringBuilder在实体类中。


推荐阅读