实体框架 5 - T4 生成的上下文类导致“参数名称重复”

Posted

技术标签:

【中文标题】实体框架 5 - T4 生成的上下文类导致“参数名称重复”【英文标题】:Entity Framework 5 - T4 generated context class causing 'duplicate parameter name' 【发布时间】:2013-05-30 01:39:27 【问题描述】:

我在 ASP.NET MVC 应用程序中使用 EF5.0。我的实体模型名为“DataModel”。模型中包含一个表值函数,它存在于我的 MSSQL 数据库中,名为 MatchingEntries。它返回一个整数 id 表。

我查看了通过 .tt (T4) 模板文件生成的 DataModel.Context.cs 文件。它有以下代码:

[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);

我在一个查询中使用此方法两次得到结果的错误,例如:

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

错误是:

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

这是从 EDMX 为表值函数生成的类的已知限制吗?使用 LINQ2SQL,我可以对数据库执行单个查询(在 MatchingEntries 的 2 个输出之间进行 JOIN),并将参数名称 @Term 替换为 @p0 和 @p1 用于调用的两个不同实例。我想让 Entity Framework 做同样的事情。

所以,我的问题是,我怎样才能让 EF 以相同的方式工作并避免“重复参数”错误?

我的后备方法是分别评估对 db.MatchingEntries 的每个调用,方法是将 ToList() 放在它们之后。我的另一个想法是将 T4 生成的 Context.cs 类中的 ObjectParameter 名称替换为每次随机生成的名称。这些感觉像是我应该能够避免的黑客攻击。

【问题讨论】:

我正在努力实现与您相同的目标。我还为全文搜索创建了一个用户定义的函数。你是如何解决这个问题的? 【参考方案1】:

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

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

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

详细回答:

DataEntitys.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);


【讨论】:

以上是关于实体框架 5 - T4 生成的上下文类导致“参数名称重复”的主要内容,如果未能解决你的问题,请参考以下文章

为什么使用T4修改EF中的实体?

T4 模板自动生成带注释的实体类文件 - 只需要一个 SqlSugar.dll

使用T4模板为EF框架添加实体根据数据库自动生成字段注释的功能

无需任何配置即可生成实体代码的 T4 模板

初用T4

使用T4模板为EF框架添加数据库实体注释