首先使用实体​​框架数据库从 SQL 查询 Xml

2023-12-23

我需要使用实体框架、LINQ 从我的 asp.net mvc(C#) 应用程序中的 SQL 查询 XML 数据。

我有一个专栏XMLValue有数据

<MetaData>
     <Reviews>1</Reviews>
     <Rating>1</Rating>
</MetaData>

我需要得到所有Customers谁有一个Ratingxml 中的 1。我已经提到过这个 stackoverflow 帖子 https://stackoverflow.com/a/1104689/111435我无法实现它。

我已经添加了 SQL 函数并将其添加到我的 edmx 中:

CREATE FUNCTION [dbo].[FilterCustomersByRating] 
    (@Rating int) 
RETURNS TABLE
AS 
RETURN
    SELECT XMLTest.*
    FROM XMLTest
    CROSS APPLY XMLValue.nodes('//MetaData') N(C)
    where N.C.value('Rating[1]', 'int')=@Rating
GO

以及以下数据库函数:

[DbFunction("XMLDBModel.Store", "FilterCustomersByRating")]
public static IQueryable<XMLTest> MyXmlHelper(int rating)
{
            throw new NotImplementedException("You can only call this function in a LINQ query");
}

下面是 linq 查询,我完全按照帖子中的方式进行了尝试,但无法使用该函数并且会抛出错误。

 var _dbCustomers = (from x in _context.XMLTests
                     where MyXmlHelper(1).Where(xh=> xh.XMLValue.Contains("1"))
                     select x);

Error:

Cannot implicitly convert type 'System.Linq.IQueryable<XMLTest>' to 'bool

如果我使用 Any(),则会出现以下错误:

 var _dbCustomers = (from x in _context.XMLTests
                          where MyXmlHelper(1).Any(xh => xh.XMLValue.Contains("1"))
                          select x);

Error:

The specified method 'System.Linq.IQueryable`1[XMLTest] MyXmlHelper(Int32)' on the type 'CustomerRepository' cannot be translated into a LINQ to Entities store expression because its return type does not match the return type of the function specified by its DbFunction attribute.

有人可以建议如何实现这一目标吗?


我认为问题是由存根函数的返回类型引起的。

你能检查一下你的返回类型吗FilterCustomersByRating方法在你的 DbContext 中吗?我认为不应该XMLTest。它应该类似于下面的代码:

[EdmFunction("TestingDbEntities", "FilterCustomersByRating")]
public virtual IQueryable<FilterCustomersByRating_Result> FilterCustomersByRating(Nullable<int> rating)
{
    var ratingParameter = rating.HasValue ?
        new ObjectParameter("Rating", rating) :
        new ObjectParameter("Rating", typeof(int));

    return ((IObjectContextAdapter)this)
    .ObjectContext
    .CreateQuery<FilterCustomersByRating_Result>("[TestingEntities]
        .[FilterCustomersByRating](@Rating)", ratingParameter);
}

在这种情况下,存根函数的返回类型将是FilterCustomersByRating_Result这是当您添加时自动生成的类FilterCustomersByRatingedmx 文件的表值函数。

CREATE FUNCTION [dbo].[FilterCustomersByRating] 
    (@Rating int) 
RETURNS TABLE
AS 
RETURN
    SELECT XMLTest.*
    FROM XMLTest
    CROSS APPLY XMLValue.nodes('//MetaData') N(C)
    where N.C.value('Rating[1]', 'int')=@Rating
GO

考虑到这一点,您的存根函数应该返回IQueryable<FilterCustomersByRating_Result> i.e.

[EdmFunction("TestingDbEntities", "FilterCustomersByRating")]
public static IQueryable<FilterCustomersByRating_Result> MyXmlHelper(int rating)
{ 
    throw new NotImplementedException("You can only call this function in a LINQ query");
}

您可以按如下所示使用它:

var dbCustomers = (from x in _context.XMLTests
                   where MyXmlHelper(1).Any(xh => xh.XMLValue.Contains("1"))
                   select x);

请注意,虽然这可行,但它会返回所有Customers。您可能需要修改FilterCustomersByRating函数接受CustomerID and rating.

试一试。

EDIT

除了上述之外,在定义时MyXmlHelper Edm函数 http://msdn.microsoft.com/en-us/library/system.data.objects.dataclasses.edmfunctionattribute%28v=vs.110%29.aspx,确保拼写FunctionName and NamespaceName是正确的。就我而言,FunctionName is FilterCustomersByRating and NamespaceName is TestingEntities它与自动生成的 DBContext 类中的值匹配。

// </auto-generated code>
public partial class TestingEntities : DbContext
{
    public TestingEntities()
        : base("name=TestingEntities")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public DbSet<XMLTest> XMLTests { get; set; }

    [EdmFunction("TestingEntities", "FilterCustomersByRating")]
    public virtual IQueryable<FilterCustomersByRating_Result> FilterCustomersByRating(Nullable<int> rating)
    {
        var ratingParameter = rating.HasValue ?
            new ObjectParameter("Rating", rating) :
            new ObjectParameter("Rating", typeof(int));

        return ((IObjectContextAdapter)this)
        .ObjectContext
        .CreateQuery<FilterCustomersByRating_Result>("[TestingEntities]
            .[FilterCustomersByRating](@Rating)", ratingParameter);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

首先使用实体​​框架数据库从 SQL 查询 Xml 的相关文章

随机推荐