如何在实体映射C#/entity Framework/Fluent中应用过滤器?

如何在实体映射C#/entity Framework/Fluent中应用过滤器?,c#,entity-framework-4,mapping,dbcontext,ef-fluent-api,C#,Entity Framework 4,Mapping,Dbcontext,Ef Fluent Api,我维护了一个几年前构建的大型web系统,它已经投入生产(我这样说是为了强调修补系统结构的复杂性) 到目前为止,该系统一直在处理数据库记录的物理排除,但是现在有必要将其更改为逻辑排除(更新表中寄存器的状态(到“D”) 我的实体由FluentApi映射。 我在上下文中的属性是使用DbSet构建的,例如: DbSet Person{get;set;} 我想知道一种仅获取实体中状态为的记录的方法!=“D”直接来自实体映射,或通过在上下文中调用实体时始终执行的整体过滤器 我尝试了一个类似于此处建议的解决方

我维护了一个几年前构建的大型web系统,它已经投入生产(我这样说是为了强调修补系统结构的复杂性)

到目前为止,该系统一直在处理数据库记录的物理排除,但是现在有必要将其更改为逻辑排除(更新表中寄存器的状态(到“D”)

我的实体由FluentApi映射。 我在上下文中的属性是使用DbSet构建的,例如: DbSet Person{get;set;}

我想知道一种仅获取实体中状态为的记录的方法!=“D”直接来自实体映射,或通过在上下文中调用实体时始终执行的整体过滤器

我尝试了一个类似于此处建议的解决方案:

实际上,它可以很好地获取我想要的数据,但是,我不能使用像“AddOrUpdate”这样的方法来更改记录,因为当我使用该解决方案时,我的属性需要是IDbSet,而不是DbSet

例如: 要使用上述链接中建议的解决方案,必须更改属性:

DbSet Person{get;set;}

为此:

IDbSet-Person{get;set;}

示例代码:

// My Entity
public class Person
{
        public int Id {get; set;}
        public string Name {get; set;}
        public string Status {get; set;}
        public ICollection<Address> PersonAddress {get; set;}
}

// My Context example
public class MyContext : DbContext
{  
    public MyContext(System.Data.Common.DbConnection conn, bool contextOwnsConnection) : base(conn, contextOwnsConnection)
    {
        ConnectionString = conn.ConnectionString;
        Database.SetInitializer<MyContext>(null);
        SetDatabaseSettings(); //NLS and regional configurations

        //Here i am calling the method built in the link above
        this.Person = new FilteredDbSet<Person>(this, a => !a.Status.Equals("D"));
    } 

    // This is now a IDbSet type
    public IDbSet<Person> Persons { get; set; }
    // The others are DbSet type
    public DbSet<Address> Adressess { get; set; }
}

// Any use of context
public class PersonsClass{

    private readonly MyContext context;

    public PersonsClass(MyContext context)
    {
        this.contexto = context;
    }

    // Considering the filter applied in MyContext constructor method 
    // this method returns all "person" with status property != D (OK)
    public List<Person> ListAllPersons()
    {
        return context.Person.toList();         
    }

    // When try to perform add or update method, the system throws the following exception:
    // "Unable to call public, instance method AddOrUpdate on derived IDbSet type 'Context.FilteredDbSet`1[Entities.Person]'. Method not found."
    // I believe that this is happening because "AddOrUpdate" method belongs to DbSet class instead of IDbSet interface.
    public void UpdatePerson(Person newPerson)
    {
        context.Person.AddOrUpdate(newPerson);
    }
}
//我的实体
公共阶层人士
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共字符串状态{get;set;}
公共ICollection PersonalAddress{get;set;}
}
//我的上下文示例
公共类MyContext:DbContext
{  
public MyContext(System.Data.Common.DbConnection conn,bool contextOwnsConnection):基本(conn,contextOwnsConnection)
{
ConnectionString=conn.ConnectionString;
Database.SetInitializer(null);
SetDatabaseSettings();//NLS和区域配置
//在这里,我调用上面链接中构建的方法
this.Person=newfiltereddbset(this,a=>!a.Status.Equals(“D”);
} 
//这现在是IDbSet类型
公共IDbSet人员{get;set;}
//其他为DbSet型
公共数据库集地址{get;set;}
}
//上下文的任何使用
公共课个人课{
私有只读MyContext上下文;
公共PersonClass(MyContext上下文)
{
this.contexto=上下文;
}
//考虑MyContext构造函数方法中应用的过滤器
//此方法返回status属性为!=D(确定)的所有“person”
公共列表列表所有人()
{
返回context.Person.toList();
}
//尝试执行添加或更新方法时,系统抛出以下异常:
//无法对派生IDbSet类型“Context.FilteredDbSet`1[Entities.Person]”调用公共实例方法AddOrUpdate。找不到方法
//我相信这是因为“AddOrUpdate”方法属于DbSet类而不是IDbSet接口。
public void UpdatePerson(Person newPerson)
{
context.Person.AddOrUpdate(newPerson);
}
}
因此,当我尝试更改此实体的记录时,会引发异常:“无法调用public,实例方法AddOrUpdate on派生IDbSet type'Context.FilteredDbSet`1[Entities.Person]'。找不到方法。”


关于如何完成它有什么建议吗?

向上投射是否会引发异常?另外,你能分享你的代码或一些片段吗?嗨,mohammedlok。我在主帖子中添加了要求的信息。感谢此方法
AddOrUpdate
相当于从数据库术语中执行
UPSERT
操作,在植入数据时非常有用。它有很多开销,不应该用在你的情况下。找到更多。您是否尝试过使用所列的
Add(tenty)
方法?另一种方法是在您的服务中实现存储库模式,然后使用LINQ over
PersonRepository
进行过滤。然而,理想情况下,这似乎并不正确。毕竟,过滤是应该在服务层完成的业务逻辑。如果没有特定PK的记录,我需要添加,如果已经有特定PK的记录,我需要更新。up casting会引发任何异常吗?另外,你能分享你的代码或一些片段吗?嗨,mohammedlok。我在主帖子中添加了要求的信息。感谢此方法
AddOrUpdate
相当于从数据库术语中执行
UPSERT
操作,在植入数据时非常有用。它有很多开销,不应该用在你的情况下。找到更多。您是否尝试过使用所列的
Add(tenty)
方法?另一种方法是在您的服务中实现存储库模式,然后使用LINQ over
PersonRepository
进行过滤。然而,理想情况下,这似乎并不正确。毕竟,过滤是应该在服务层完成的业务逻辑。如果没有特定PK的记录,我需要添加,如果已经有特定PK的记录,我需要更新它。