1

I'm using EF5.0 in an ASP.NET MVC app. My Entity Model is named 'DataModel'. Included in the model is a table-valued function that exists in my MSSQL database, named MatchingEntries. It returns a table of integer ids.

I've looked at the DataModel.Context.cs file, that gets generated via the .tt (T4) template file. It has the following code in it:

[EdmFunction("DataEntities", "MatchingEntries")]
public virtual IQueryable<Nullable<int>> MatchingEntries(string term)
{
    var termParameter = term != null ?
        new ObjectParameter("Term", term) :
        new ObjectParameter("Term", typeof(string));

    return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<Nullable<int>>("[DataEntities].[MatchingEntries](@Term)", termParameter);
}

The error I am getting results from using this method twice within the one query, such as:

IQueryable<int> one = db.MatchingEntries("\"one*\"");
IQueryable<int> two = db.MatchingEntries("\"two*\"");
List<int> both = one.Intersect(two).ToList();

The error is:

A parameter named 'Term' already exists in the parameter collection. Parameter names must be unique in the parameter collection.
Parameter name: parameter

Is this a known limitation of the classes generated from an EDMX for table-valued functions? With LINQ2SQL I am able to execute this a a single query to the database (that does a JOIN between the 2 outputs from MatchingEntries) and it replaces the parameter name @Term with @p0 and @p1 for the two different instances of the call. I'd like to make Entity Framework do the same.

So, my question is, how can I get EF to work in the same manner and avoid the 'Duplicate parameter' error?

My fallback is to evaluate each call to db.MatchingEntries separately, by putting ToList() after them. My other idea has been to replace the ObjectParameter name in the T4 generated Context.cs class with something randomly generated each time. These feel like hacks that I should be able to avoid.

4

1 回答 1

0

这个答案是 Linq to Entities 特定的。这不必在 Linq to SQL (Linqpad) 中完成。

感谢这个问题,我得到了一个可行的解决方案的指针:

  • 扩展自动生成的 DBContext 类(部分类)
  • 在分部类中添加一个带有两个参数的方法
  • 在调用时,将索引作为第二个参数传递

详细答案:

数据实体.my.cs:

[EdmFunction("DataEntities", "MatchingEntries")]
public virtual IQueryable<Nullable<int>> MatchingEntries(string term, int index)
{

    string param_name = String.Format("k_{0}", index);

    var termParameter = term != null ?
        new ObjectParameter(param_name, term) :
        new ObjectParameter(param_name, typeof(string));

    return ((IObjectContextAdapter)this).
    ObjectContext.CreateQuery<Nullable<int>>(
    String.Format("[DataEntities].[MatchingEntries](@{0})", param_name), 
    termParameter);
}

调用函数:

foreach (string teil in such)
{
     index++;
     if (teil.Trim() != "")
         res = res.Join(db.MatchingEntries("\"" + teil + "*\"", index), l => l.ID, s => s.KEY, (l, s) => l);

}
于 2013-06-19T09:55:27.257 回答