My invoice class has a StringBuilder
property so that if adjustments are made, the user adds notes as the details of why the adjustment was made. This property is set to a new empty StringBuilder
upon creation. Only in edit mode will it get .Append()
added to. From what I understand, this is more efficient than using adjustmentNotes += newAdjustmentNotes
every time new notes are added.
My Invoice.cs class is as follows.
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; }
}
When populating my list or details view, I query the database as follows:
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();
}
Then I get the following error message.
System.NotSupportedException: 'Values of type 'StringBuilder' can not be converted to string.'
But according to Microsoft documentation, other questions on this forum, and various resources this is the proper way to accomplish this.
I can certainly change it back to a string and use += as needed. There will not be too many notes for this particular property, but can someone please explain what I am doing wrong? Thank you so much!
EDIT: For clarification, here is my InvoiceListItem
model class:
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; }
}
EF Core says in the error message:
I don't know how convert
StringBuilder.ToString()
to target database language.
The solution is to do the conversion after the query:
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()
}
);
If you want limit the returned properties in the query, you can use intermediate type like:
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: I found no information about EF Core support StringBuilder
type, but your context's model is build with success then EF Core seems to support StringBuilder
type...
If there is support, it seems very limited (see the error in your question). Maybe you can consider use String
instead of StringBuilder
in entity class.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.