Skip to content

Instantly share code, notes, and snippets.

@mrameezraja
Created September 1, 2021 14:12
Show Gist options
  • Save mrameezraja/9f15ad624e2cba8ac24066cdf271453b to your computer and use it in GitHub Desktop.
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"
//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;
}
}
@akhanalcs
Copy link

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; }

@mrameezraja
Copy link
Author

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