Created
September 1, 2021 14:12
-
-
Save mrameezraja/9f15ad624e2cba8ac24066cdf271453b to your computer and use it in GitHub Desktop.
EF Core: Get the exact fields causing the issue "string or binary data would be truncated"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Usage | |
public class TestController : Controller | |
{ | |
private readonly IMyContext _context; | |
public TestController(IMyContext context) | |
{ | |
_context = context; | |
} | |
public async Task<string> Post(Record record) | |
{ | |
try | |
{ | |
record.FirstName = "i am a longer name than the db field is expecting!"; | |
await _context.Records.AddAsync(record); | |
await _context.SaveChangesAsync(); | |
} | |
catch(Exception ex) | |
{ | |
// DbUpdateException | |
var fields = _context.GetEvilFields("Records", record); | |
// you will get all the fields which has values greater than db field length | |
} | |
} | |
} | |
// Implentation | |
public interface IMyContext | |
{ | |
DbSet<Record> Records { get;set; } | |
Task<int> SaveChangesAsync(); | |
Dictionary<string, string> GetEvilFields(string tableName, object instance); | |
} | |
public class MyContext: DbContext, IMyContext | |
{ | |
public DbSet<Record> Records { get;set; } | |
public Dictionary<string, string> GetEvilFields(string tableName, object instance) | |
{ | |
Dictionary<string, string> result = new Dictionary<string, string>(); | |
var tableType = this.Model.GetEntityTypes().First(c => c.GetTableName().Contains(tableName)); | |
if (tableType != null) | |
{ | |
int i = 0; | |
foreach (var property in tableType.GetProperties()) | |
{ | |
var maxlength = property.GetMaxLength(); | |
var prop = instance.GetType().GetProperties().FirstOrDefault(_ => _.Name == property.Name); | |
if (prop != null) | |
{ | |
var length = prop.GetValue(instance)?.ToString()?.Length; | |
if (length > maxlength) | |
{ | |
result.Add($"{i}.Evil.Property", prop.Name); | |
result.Add($"{i}.Evil.Value", prop.GetValue(instance)?.ToString()); | |
result.Add($"{i}.Evil.Value.Length", length?.ToString()); | |
result.Add($"{i}.Evil.Db.MaxLength", maxlength?.ToString()); | |
i++; | |
} | |
} | |
} | |
} | |
return result; | |
} | |
} |
Hi @affableashish , i haven't tested it with EF6 yet and tableType.GetProperties()
comes directly from database.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Your line 48, i.e.
this.Model.GetEntityTypes()
and 56, i.e.property.GetMaxLength();
don't seem to be available in EF 6.Can you suggest an alternative?
And one more question:
Does
tableType.GetProperties()
come directly from Database, for eg:varchar(10)
defined in database table?OR are these properties coming from Database table model fields defined in our code? For eg:
[Column("SomeColumnName", TypeName="varchar(10)")] // This is what I annotated the field with
public string SomeColumnName { get; set; }