用的DbContext查找包括 - 凡与主键的lambda [英] DBContext Find with Includes - where lambda with Primary keys

查看:1316
本文介绍了用的DbContext查找包括 - 凡与主键的lambda的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写一个通用库使用的DbContext EF接口。

I am writing a generic repository to interface with EF using DBContext.

我有收到一个主键值,并返回实体的通用get()方法:

I have a generic Get() method which receives a primary key value and returns the entity:

public class DALRepository<DALEntity> : IDisposable, IGenericRepository<DALEntity> where DALEntity : class
{
private IDbSet<DALEntity> dbSet;
private NWEntities context;

public DALRepository()
{
  context = new NWEntities();
  context.Configuration.LazyLoadingEnabled = false;
  dbSet = context.Set<DALEntity>();
}

下面是一个简单的get方法 - 只是工程上的PK - 正是我想要的

Here's a simple get method - just works on the PK - exactly what I want.

public DALEntity Get(string ID)
{
   return dbSet.Find(ID);
}



我现在想改变这个,让消费者在名单通过包括 - 所以,以及只返回一个客户,他们可以要求退回订单为好。这里就是我遇到的麻烦。如果我这样做:

I now want to change this to allow the consumer to pass in a list of includes - so as well as returning just a customer they can request to return the orders as well. Here's where I'm running into trouble. If I do this:

public DALEntity Get(string ID, IEnumerable<string> IncludeEntities = null)
{
      IQueryable<DALEntity> query = dbSet;
      query = IncludeEntities.Aggregate(query, (current, includePath) => current.Include(includePath));
}



我不能用找到的IQueryable的。而且我找不到()直接,因为我无法通过包括它。如果我对IQueryable的使用where拉姆达代替,我怎么告诉它使用的实体的PK?我想我可以有坚持泛型类型必须实现一个定义良好的主列名的一些IPkey接口,如ID一般的约束,但后来我不能利用的DbContext产生的实体,因为他们woudl必须实现这个接口。我可以改变T4要做到这一点,如果我需要 - 我已经改变了它发出的XML注释所以没有太多反对的 - 但没有人有一个简单的方法是什么?我想我需要的是一个重载的find()方法,它接受包括列表。

I can't use find with the IQueryable. And I can't Find() directly because I can't pass includes to it. If I use a where lambda instead on the IQueryable, how do I tell it to use the PK of the entity? I guess I could have a generic constraint that insists the generic type must implement some IPkey interface with a well-defined primary column name such as "ID", but then I can't use the entities generated by DBContext as they woudl have to implement this interface. I can change the T4 to do this if I need - and I've already changed it to emit XML comments so not too averse to that - but does anyone have a simpler way? I suppose what I need is an overloaded find() which accepts a list of includes.

所以我的问题是无论是如何使用查找具有包括,或如何写拉姆达它知道PK?我不能收到这样的拉姆达的,因为这将最终由WCF服务消费的参数。

So my question is either how to use Find with includes, or how to write the lambda where it knows the PK? I can't receive such a lambda as a parameter as this will ultimately be consumed by a WCF service.

推荐答案

奇怪的种类在回答自己的问题,但如果任何人在这里有这个问题就是我所做的。我用动态LINQ的东西,并用。凡串重载版本()。我以前提到的链接之一,弄清楚如何抓住主键(我的是从的DbContext以及),该方法现在看起来是这样的:

Kind of wierd answering your own question but in case anyone else has this issue here's what I did. I used the dynamic LINQ stuff and used the string overloaded version of .Where(). I used one of the links mentioned to figure out how to grab the primary key (and mine is from a DBContext as well), and the method now looks like this:

public DALEntity Get(string ID, IEnumerable<string> IncludeEntities = null)
{
  var set = ((IObjectContextAdapter)context).ObjectContext.CreateObjectSet<DALEntity>();
  var entitySet = set.EntitySet;
  string[] keyNames = entitySet.ElementType.KeyMembers.Select(k => k.Name).ToArray();
  Debug.Assert(keyNames.Length == 1, "DAL does not work with composite primary keys or tables without primary keys");

  IQueryable<DALEntity> query = dbSet;
  query = IncludeEntities.Aggregate(query, (current, includePath) => current.Include(includePath));

  query = query.Where(keyNames[0] + "= @0", ID);
  return query.FirstOrDefault();
}

这篇关于用的DbContext查找包括 - 凡与主键的lambda的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆