【问题标题】:How to get names of all required fields in new row with EF?如何使用 EF 获取新行中所有必填字段的名称?
【发布时间】:2014-09-12 12:26:20
【问题描述】:

我正在使用 EF(db first)并尝试使用下一个代码在表中添加新行:

var user = new User();

//Some logic to fill the properties

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

在 EF 上保存更改之前,我想验证是否已填充所有必需的(非 null 且没有默认值)属性。我怎样才能获得所有这些字段?

我尝试了几种方法,但无法达到所需的结果。最后一次尝试是这样的:

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;

【问题讨论】:

  • 在您的 edmx 文件上使用自定义 .tt 生成一个不可为空的无默认属性列表会不会更容易?我不明白你怎么能从那里得到带有“默认值”的属性(但我可能会错过一些东西)。

标签: c# entity-framework


【解决方案1】:

使用必填字段作为参数创建一个构造函数。

我总是将我的域对象与我的 EF 对象(DTO 对象)分开。域对象只有一个带有必需字段的构造函数。当我想保存这些对象时,我会将它们转换为 DTO 对象。

【讨论】:

  • 这与手动验证每个必填字段没有区别。我有近 90 个字段,其中大约 40 个是必需的。这将是一个 laaarge 构造函数。
  • 您有 90 个字段代表一类数据?不能将其重构为更合乎逻辑的配对吗? stackoverflow.com/questions/174968/…
【解决方案2】:

您是否仔细研究过模型类的 DataAnnotations?利用这些(并使用与 EF 为您创建的一个单独的对象),您可以从模型级别获得非常重要的内置到模型中的验证。此外,正如 L01NL 所指出的,您可以让构造函数接受需要数据的参数。

可以找到很多关于模型和验证的信息,一个这样的例子是: http://msdn.microsoft.com/en-us/library/dd410405(v=vs.100).aspx

(浏览此主要部分及其子部分)

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

}

【讨论】:

    猜你喜欢
    • 2015-03-11
    • 1970-01-01
    • 2011-10-23
    • 2020-02-06
    • 1970-01-01
    • 1970-01-01
    • 2014-08-07
    • 1970-01-01
    • 2019-12-29
    相关资源
    最近更新 更多