Extending LINQ to SQL generated classes

2019-06-13 02:32发布

问题:

I have picked LINQ to SQL as ORM framework for ASP .NET MVC3 project. Everything was good before I was faced with need to put additional field 'Confirm Password' to registration form. As it was mentioned in one question on SO (unfortunately I can't find it at the moment), it's better to use interface to extend generated LINQ to SQL classes with validation attributes, instead of having another class for storing validation attributes. So here we go:

public interface IRegTry
    {
        [Required]
        [Email]
        string EMail { get; set; }

        [Required]
        [StringLength(100, ErrorMessage = "Should not exceed 100 symbols")]
        string FirstName { get; set; }

        [Required]        
        string Password { get; set; }        

    }

    [MetadataType(typeof(IRegTry))]
    public partial class RegTry : IRegTry { }

RegTry class is generated class by LINQ to SQL based on database entity.

On the View we have confirm password field, which should make sure that two typed password equals to each other.

So here we adding it:

public class RegTryViewModel : RegTry
{
    [Required]
    [EqualTo("Password", ErrorMessage = "You should type two identical passwords to continue")]
    public string ConfirmPassword { get; set; }
}

View is strongly typed view with RegTryViewModel model.

I just ask here to make sure I'm doing everything right. The thing that makes me feel uncomfortable is that I spread validation logic between IRegTry interface and the RegTryViewModel class. But I can't add ConfirmPassword property to IRegTry interface because base SQL to LINQ class doesn't has it at all. Thanks in advance guys!

回答1:

I know that you already accepted an answer for this but I think it may be better to set this up using partial classes. As long as you set up the partial class in the same namespace with the same name, everything will get set up automatically. Here is an example of how I set this up in one of my projects:

namespace OperationsMetrics
{
[MetadataType(typeof(ClientStatMD))]
public partial class client_wkly_stat : IValidatableObject
{
    public class ClientStatMD
    {
        [Required(ErrorMessage = "Client selection is required")]
        public virtual int client_id { get; set; }
        [Required(ErrorMessage = "SLAs met is required")]
        public virtual int wkly_sla_met { get; set; }
        [Required(ErrorMessage = "Total SLAs possible is required")]
        public virtual int wkly_sla_req { get; set; }
        [Required(ErrorMessage = "Number of input files is received")]
        public virtual int num_inp_files_rec { get; set; }
        [Required]
        public string client_name { get; set; } 

    }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (wkly_sla_met > wkly_sla_req)
        {
            yield return new ValidationResult("SLAs met cannot be greater that SLAs possible");
        }


    }
    public string client_name { get; set; } //this isn't a part of the actual db object but can still be accessed in the Validate method
}

}

You can set up the Partial Class as an IValidatableObject which implements its own Validate method. You can have a check for Confirm==Password in your Validate method.

You can get some more information in this Pluralsight Video



回答2:

If you are using View Model classes, you don't need validation logic connected to your DAL Model classes, so you shouldn't need that validation interface linked to the DAL Model class.