C#如何知道哪些属性已设置为验证&;标志EFCore修改标志

C#如何知道哪些属性已设置为验证&;标志EFCore修改标志,c#,validation,object,entity-framework-core,C#,Validation,Object,Entity Framework Core,本质上,我想知道是否有办法知道对象上的哪些属性已经设置,以便知道哪些属性要标记为EFCore和我的验证器已修改 比如说,我有两门课: class-Foo { 公共int Id{get;set;} 公共字符串名称{get;set;} 公共字符串内容{get;set;} 公共条TheBar{get;set;} 公共ICollection条{get;set;} } 分类栏 { 公共int Id{get;set;} 公共字符串名称{get;set;} } 我还必须假设空值或默认值可以是任何属性的有效值

本质上,我想知道是否有办法知道对象上的哪些属性已经设置,以便知道哪些属性要标记为EFCore和我的验证器已修改

比如说,我有两门课:

class-Foo
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共字符串内容{get;set;}
公共条TheBar{get;set;}
公共ICollection条{get;set;}
}
分类栏
{
公共int Id{get;set;}
公共字符串名称{get;set;}
}
我还必须假设空值或默认值可以是任何属性的有效值。这意味着我不能像
if(prop.equals(default(PropType)))
这样检查属性是否已设置

我目前拥有的是一种通用更新方法,如下所示:

public ExecutionResult ExecuteUpdate(TModel模型,参数表达式[]updatedProperties)
{
//验证和EFCore调用
}
使用该方法,我可以做类似的事情,这允许我手动设置哪些属性将根据Http端点进行更新。即,更新密码端点只会更改模型上的密码属性,而不会更改模型上的所有属性:

var myFooOne=新Foo
{
Id=1,
Name=“新名称”,
Content=“一些新内容”
}
//这允许我仅验证更新的属性,并允许我将模型附加到EFCore,并且仅在修改的属性上设置修改标志以创建最佳查询
ExecuteUpdate(myFooOne,foo=>foo.Name,foo.Content);
当前解决方案的问题是,当我需要验证/更新任何非基本属性时。使用我当前的解决方案,我必须执行以下操作:

//只更新了TheBar属性的Name属性
var myFooTwo=新Foo
{
Id=1,
TheBar=新酒吧
{
//数据库中已存在的特定条的Id
Id=5,
Name=“新名称”
}
}
ExecuteUpdate(myFooTwo,foo=>foo.TheBar.Name);
这有两个问题,使用选择器,我只能得到与直接对象本身一样具体的结果,我无法通过这种方式告诉EFCore,BAR属性上的哪些特定属性是脏的,我只能将整个属性对象标记为脏的(这是低效的)。第二,像这样的表达式选择器甚至不能处理比选择立即属性更复杂的事情,例如,
foo.TheBar
很好,但是
foo.TheBar.Name
抛出一个ArgumentException。对于集合,甚至更进一步的嵌套对象,这会变得更加复杂

我的一个想法是将我的所有类型包装在一个包装器中,如下所示:

enum包装器状态
{
不详,
未设置,
设置
}
类包装器
{
T值{get;}
包装器状态状态{get;}
}
类实体
{
包装器Id{get;set;}
包装条{get;set;}
//其余属性和所有模型的情况相同
}
然后,在验证和更新时,我可以执行以下操作:

var foo=new FooEntity
{
Id=新包装器
{
值=1,
Status=WrapperStatus.Set
},
Name=新包装器
{
Value=“新名称”,
包装器状态。设置
}
}
基本上,我的想法是围绕每个模型创建一个包装器,每个模型的每个属性都要用
WrapperStatus
标记,我可以根据需要添加任意多个不同的标记:
Updated、Null、UnChanged
等等。 一旦我验证了模型(这很容易,因为我知道需要根据标志检查哪些属性),我就可以使用适配器将WrapperModel转换为实际模型,并将其传递给EFCore,同时还可以轻松地在所需的属性上设置Modified标志。我还没有这样做的唯一原因是,它本质上需要创建两次模型,一次用于EFCore模型,另一次用于包装器模型。现在,我可以使用
操作符
关键字和一些静态初始值设定项使包装器更容易初始化,但我想先看看是否有更简单的方法


我知道这是很多信息,但我可以澄清任何需要的信息。

EF Core已经在跟踪实体上的更改,您不需要复制它。对于我的验证器,也可以这样说,我希望名称字段不为null或空。此检查只应在更新名称字段时进行。但是,并非所有Http端点都会更新名称字段,因此如果端点只更新内容字段,那么验证程序将失败,因为它不知道不应该检查名称字段,而应该只检查内容字段。基本上,验证器需要知道应该验证哪些属性,然后将该信息传递给EFCore。如果要保存实体,最好验证整个实体,以便保存有效的实体。验证足够便宜,可以验证整个实体,而不是构建复杂的跟踪系统,但是每次我想要验证某个实体时,我都必须检索整个实体。或检索实体的整个集合,以及可能的任何嵌套实体。如果某个属性依赖于要验证的另一个属性的值,则我可以检索从属属性,但许多属性都可以在不需要其他属性的情况下进行验证。您已经有一个要验证的实体实例。你能展示验证实体的代码吗?EF Core已经在跟踪实体上的更改,你不需要复制它。对于我的验证器,也可以说我希望名称字段不为null或空。此检查只应在更新名称字段时进行。但是,并非所有Http端点都会更新名称字段,因此如果一个端点只更新内容字段,那么验证程序将失败