2

I'm using EF(db first) and trying to add new row in table using the next code:

var user = new User();

//Some logic to fill the properties

context.Users.AddObject(user);
context.SaveChanges();

Before saving changes on EF i want to verify that all required (not null and with no default value) properties are filled. How can i get all such fields?

I've tried few ways, but can't achieve needed result. The last try was like that:

var resList = new List<PropertyInfo>();

var properties = type.GetProperties(BindingFlags.DeclaredOnly |
                               BindingFlags.Public |
                               BindingFlags.Instance).Where(p => !p.PropertyType.IsGenericType);

foreach (var propertyInfo in properties)
{
    var edmScalarProperty =
        propertyInfo.CustomAttributes.FirstOrDefault(
            x => x.AttributeType == typeof (EdmScalarPropertyAttribute));
    var isNullable = true;
    if (edmScalarProperty != null)
    {
        var arg = edmScalarProperty.NamedArguments.FirstOrDefault(x => x.MemberName == "IsNullable");
        if (arg != null)
        {
            isNullable = (bool) arg.TypedValue.Value;
        }
    }

    if (!isNullable)
    {
        resList.Add(propertyInfo);
    }
}

return resList;
LbISS
  • 623
  • 2
  • 10
  • 25
  • 1
    Would'nt it be easier to generate a list of non nullable no default properties with a custom .tt on your edmx file ? I don't see how you could get the properties with "default values" out of there (but I may miss something). – Raphaël Althaus Sep 12 '14 at 12:33

2 Answers2

2

Create a constructor with the required fields as parameters.

I always separate my domain objects from my EF objects (DTO objects). The domain object has only one constructor with the required fields. When I want to save these objects I convert them to DTO objects.

L01NL
  • 1,753
  • 1
  • 13
  • 17
  • It doesn't differs from manual verifying each required field. I have nearly 90 fields, and about 40 of them is required. It'll be a laaarge constructor. – LbISS Sep 19 '14 at 05:29
  • 1
    You have 90 fields representing a single class of data? Couldn't it be refactored into more logical pairings? http://stackoverflow.com/questions/174968/how-many-parameters-are-too-many – Kritner Sep 19 '14 at 19:36
2

Have you looked at all into DataAnnotations for your model classes? Utilizing these (and using a separate object from the one EF creates for you) you can get pretty significant validation built into your models from the model level. Additionally, as L01NL pointed out, you can have your constructor take in parameters that require data.

Lots of information on Model and Validation can be found, one such example is: http://msdn.microsoft.com/en-us/library/dd410405(v=vs.100).aspx

(look through this main section and its subsections)

using System.ComponentModel.DataAnnotations

public class Foo
{
    public Guid Id { get; private set; }

    [StringLength(50),Required]
    public string FooName { get; private set; }

    [Required]
    public int Age { get; private set; }

    // etc props

    public Foo(string fooName, int age)
    {
        if (string.IsNullOrEmpty(fooName))
            throw new ArgumentException("FooName cannot be null or empty"); // note there is also a "minimum length" data annotation to avoid doing something like this, was just using this as an example.

        this.Id = Guid.NewGuid();
        this.FooName = fooName;
        this.Age = age;
    }
}

public class YourController
{

    [HttpPost]
    public ActionResult Add(Foo foo)
    {
        if (!ModelState.IsValid)
            // return - validation warnings, etc

        // Add information to persistence
        // return successful add?
    }

}
Kritner
  • 13,557
  • 10
  • 46
  • 72