实体包装 - 自定义

时间:2011-03-31 07:47:37

标签: c# .net entity-framework entity-framework-4

我想找到一种解决方法来完成一个简单的解决方案,以便通过EF自动化某些操作。 我需要它在保存和检索过程中修改查询结果时的接管,但是这个类将能够使其适用于任何类型的实体。

示例:我有一个MyTestDb。所以在我的C#项目中,我创建了一个新的实体模型(MyTEstDbModel.edmx),并生成了相对的POCO类。 好吧,兴趣点可能是实现一个新的自定义类,如下所示:

class Example
{
   private ObjectContext _context;
   private Example(ObjectContext obj) { _context = obj; }

   public void Store(ObjectSet<???generic???> os)
   {
       // problem here: I dont't know the type contained in ObjectSet
       // but if I Knew its type, I could make a work like this:
       // -> foreach every instance in objectSet to check if exist some property 
       // via reflection, if i found them, then I set always the same values.
       // Why this? Because all my db contains some common filed 
       // like (createdByUser, TimeToUpdate, and so on..), so it wold be boring 
       // setting all those fileds from any point of program.
   }

public void Retrive(ObjectSet<???generic???> os)
{
   // here problem too: all my queries will be filtered by one or more value
   //  fileds, but I cannot use lambaExpression cos I don't Know the type 
   // contained in objectSet<..>
}
//....

最后,在程序的任何一点,代码应如下所示:

Example obj = new Example(myEntityContext); //-> global

var result = myEntityContext.ObjectSetTyped.Where(..lambaExpression..condition)
result.someProperty = "...";
obj.Store(result); // store method will fill all other boring filed automatically.

有人可以给我一些关于我的问题的提示,帮助和建议吗?

提前致谢...

更新

现在,只是另一个问题。我将通过检索方法过滤我的ObjectSet,如下所示:

public void Retrieve<TEntity>(IQueryable<TEntity> ooo) where TEntity : IC
{
    ooo = ooo.Where(p => p.Filed == "MyDefaultValue");
}

但是,从外部方法来看,不是objectSet结果会受到我的过滤器的影响。 怎么样......?

MyEntities ent = new...
MyWrapper wrap = new MyWrapper();
wrap.Retrieve(ent.Users);

//问题在这里 - &gt;用户objectSet始终是相同的..

2 个答案:

答案 0 :(得分:1)

定义允许您执行此操作的界面。例如:

public interface IEntity
{
  DateTime CreatedAt { get; set; }
  string CreatedBy { get; set; }
}

您需要在实体中“实施”此接口。例如,您可以修改T4模板生成实体或在部分类中实现它。这两个属性必须已在模型中定义,因此实现只是声明性的:

public partial class MyEntity : IEntity // That's all
{ }

现在您可以定义Store,如:

public void Store<TEntity>(TEntity entity) where TEntity : IEntity
{
  ...
}

可以使用查询完成相同的操作,但您可以定义自定义扩展方法:

public static IQueryable<TEntity> GetUserEntities(this IQueryable<TEntity> query, string user) 
    where TEntity : IEntity 
{
   return query.Where(e => e.CreatedBy == user);
}

您只需定义您的查询,如:

var result = myEntityContext.MyEntities.GetUserEntities("someName");

其他方法是在自定义上下文中定义GetQuery:

public IQueryable<T> GetQuery<T>() where T : IEntity
{
    var query = GetObjectSetSomehow;
    return query.ApplyGlobalConditions(); // Just another extension with your conditions
}

我不是存储库模式的忠实粉丝,但通常你要做的就是接近通用存储库,所以检查例如this post。这只是一些可以进一步扩展的例子。

答案 1 :(得分:0)

是的,我只想要一个通用的方法,同样我用数据集和数据表实现了......但似乎无法实现..

..嗯..但是,让我在下面的代码片段中显示yuo,动态关键字看起来像是有希望的东西....也许我会解决问题..?

    public ObjectSet<dynamic> Retrieve(string entity, string context)
    {
        Type myObjectContextType = Type.GetType(context);            
        ConstructorInfo cs = myObjectContextType .GetConstructor(new Type[] { });
        dynamic myObjContext = cs.Invoke(new object[] { });

        Type t = Type.GetType(entity);
        ConstructorInfo xi = t.GetConstructor(new Type[] { });
        dynamic UserEntity = xi.Invoke(new object[] { });

        !problem here!
        ObjectSet<?????> os = myObjContext.UserEntity.Where(...) 

        return ...           

    }

我很惊讶..EF是一种很有效的工具,可以更有效地开发方式,但是太少“generalizalbe”