GitHub in your pocket. Built with Passion.
- Introduction
- Features
- Feedback
- Contributors
- [how to-use](#how to-use)
- Backers
- Sponsors
- Acknowledgments
EZREB (tunisian word mean speed up) is a set of tools to help dotnet developers speed up building their application.
Available On Nuget Packages
https://www.nuget.org/packages/FluentValidationWithEntityValidation/1.0.0
A few of the things you can do with EZREB:
- Auto Detect EF Core Entity Constraint ( unique,foreign-key,not-nullable)
- Custom Mapping Your DTO properties
- Ignore Specific property for manual validation
- Use Validator directly(ForeignKey,IsUnique...)
- Add Auto Filter Class (Incoming)
Feel free to send us feedback on Linkedin or file an issue. Feature requests are always welcome. If you wish to contribute, please take a quick look at the guidelines!
If there's anything you'd like to chat about, please feel free to send a message on my email Email
This project follows the all-contributors specification and is brought to you by these awesome contributors.
Let's suppose you have an entity **Person ** :
public class Person
{
private Person()
{
// This For EF Core
}
public int Id { get; set; }
public string Name { get; set; } // this maximum length would be 25
public int Age { get; set; }
public string Email { get; set; }
public string Username { get; set; } //this should be unique
}
to spice things up , let's add some constraint:
- Name maximum length: 25
- Username should be unique
am fan of separating concerns ,so I'll create PersonConfiguration File to add those constraint:
public class PersonConfiguration: IEntityTypeConfiguration<Person>
{
public void Configure(EntityTypeBuilder<Person> builder)
{
builder.HasKey(p => p.Id); // this for primary key
builder.HasIndex(p => p.Username).IsUnique();
builder.Property(p => p.Name).HasMaxLength(25);
}
}
I think dotnet has make it simple enough to read the code
to accept data from user we cannot use our entity class ,so we need to create a DTO and a validator ...
PersonCreateIn(DTO):
public class PersonCreateIn
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
public string Username { get; set; }
}
now our DTO is missing validations (Name maximum length, Username unique constraint )
adding validation would require installing FluentValidation
ProductValidator:
public class PersonValidator : AbstractValidator<PersonCreateIn>
{
public PersonValidator()
{
RuleFor(p => p.Name).Length(25);
RuleFor(p => p.Username). // How we define unique constraint ?
}
}
add unique constraint would require creating custom extension method for FluentValidation , I doubt you want that
you don't have to build with all the mess of validating your property constraint or creating a custom method we give you a **IsUnique ** method:
public class PersonValidator : AbstractValidator<PersonCreateIn>
{
public PersonValidator(ApplicationDbContext applicationDbContext)
{
var query = applicationDbContext.Set<Person>() as IQueryable; // <- add this also
RuleFor(p => p.Name).Length(25);
RuleFor(p => p.Username).IsUnique<PersonCreateIn, string, Person>(query,"Username"); // <- here is it
}
}
that was easy, is it ?!
but what if we add a foreign Key ?! how to validate it
before adding a foreign-key we need :
- Create Country class
- Update our "Product" class to point to "Country"
- update PersonConfiguration to tell EF Core about our foreign-key
Country class
public class Country
{
private Country()
{
// This For EF Core
}
public int Id { get; set; }
public string Name { get; set; }
}
Updated Person class
public class Person
{
private Person()
{
// This For EF Core
}
... // truncated for readability
public Country Country { get; set; } //
public int CountryId { get; set; } //
}
Now let's update PersonConfiguration
public class PersonConfiguration: IEntityTypeConfiguration<Person>
{
public void Configure(EntityTypeBuilder<Person> builder)
{
... // truncated for readability
builder.HasOne(p => p.Country); // this add foreign key
}
}
note: add your migration and update database
Perfect .
now let's add our DTO property to verify foreign key
public class PersonCreateIn
{
... // truncated for readability
public int CountryId { get; set; } //
}
all good let's update our validation class
public class ProductValidator : AbstractValidator<PersonCreateIn>
{
public ProductValidator(ApplicationDbContext applicationDbContext)
{
... // truncated for readability
var country_query = applicationDbContext.Set<Country>() as IQueryable;
RuleFor(p => p.CountryId).IsForeignKey<PersonCreateIn, int, Country>(country_query);
}
}
Simple is it ?! but if you're a big procrastinator like me you wouldn't take care if applying all these roles by yourself
public class PersonCreateInValidator:EntityValidator<PersonCreateIn,Person,ApplicationDbContext>
{
public static ICollection<string> IgnoreList { get; set; } = new List<string>
{
};
public static IDictionary<string, string> FieldMappers = new Dictionary<string, string>()
{
};
public PersonCreateInValidator(ApplicationDbContext context) : base(context, IgnoreList, FieldMappers)
{
}
}
EntityValidator : base class you should inherit from
so this will inspect your PersonCreateIn Dto properties compare it with Person Entity and add the needed constraints
- Username unique constraint
- CountryId foreign Key constraint
- Name string max length
let's suppose you have DTO custom property name
example best way to example
public class PersonCreateIn
{
// public string Name { get; set; }
public string FirstName { get; set; } // this should reference Name property
public int Age { get; set; }
public string Email { get; set; }
public string Username { get; set; }
public int CountryId { get; set; }
}
if run your code your will stub into an Exception : EntityColumnNotFoundException this would tell FirstName is not defiend on Person
Solution:
public class PersonCreateInValidator:EntityValidator<PersonCreateIn,Person,ApplicationDbContext>
{
public static ICollection<string> IgnoreList { get; set; } = new List<string>
{
};
public static IDictionary<string, string> FieldMappers = new Dictionary<string, string>()
{
{"Name", "FirstName"}
};
public PersonCreateInValidator(ApplicationDbContext context) : base(context, IgnoreList, FieldMappers)
{
}
}
This will tell EntityValidator Person->Name mapped to PersonCreateIn->FirstName
Thank you to all our backers!
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]