实体框架:"伪造"可查询的导航属性 [英] Entity Framework: "Faking" a queryable navigation property

查看:102
本文介绍了实体框架:"伪造"可查询的导航属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要打假导航在EF-映射类属性。

I'd like to "fake" a navigation property in an EF-mapped class.

考虑一个例子,我有书(由ISBN标识)和购买(按国际标准书号标识太) - 注意,书和采购是故意不直接映射到对方

Consider an example where I have books (identified by "isbn") and purchases (identified by "isbn" too) - note that Books and Purchases are intentionally NOT directly mapped to each other.

现在我想创建一个扩展方法对于周易,返回本书所有购买在可查询的格式,像

Now I'd like to create an extension method for "Book" that returns all purchases of the book in a queryable format, something like

public class Book
{
    public virtual string isbn { get; set; }
    public virtual string name { get; set; }


    // Pseudo-code .. does not work, throws an exception
    // "LINQ to Entities does not recognize the method [...], and this method cannot
    // be translated into a store expression
    public virtual IQueryable<Purchase> get_purchases(DbContext context)
    {
        return context.Purchases.Where(purchase => purchase.isbn == this.isbn);
    }
}

public class Purchase
{
    public virtual string isbn { get; set; }
    public virtual double price { get; set; }
}

所以在最后,我想要做任意的查询,如(完全随机的例子)

So in the end, I'd like to do any arbitrary queries such as (completely random example)

dbContext.Books.Where(book => book.get_purchases(dbContext).Where(purchase => purchase.price > 90))

但正如评论所说,我的方法是行不通的,因为EF / LINQ不能使用我的扩展方法。

But as mentioned in the comment, my approach doesn't work, as EF / LINQ can't make use of my extension method.

有什么办法做这个?
语句应该是可翻译成一个SQL查询;我不想使用像.ToList()的任何方法,以避免不必要的retreiving庞大的数据集。

Is there any way to do this? The statement should be translateable into a single SQL query; I don't want to use any methods like .ToList() to avoid retreiving unnecessarily huge datasets.

莫非这部作品通过创建一个返回

Could this work by creating a function that returns an

Expression<Func<Book, IQueryable<Purchase>>>

或那样的东西吗? ?(因为我在写作表达绝对可怕无法试试这个还),或是否有任何其他的办法

or anything of that kind? (Couldn't try this yet as I am absolutely horrible at writing expressions), or is there any other approach?

免责声明:这是一个很好的理由没有明确映射购买< - >债券;不应该是相关的问题,但背景是基于Floremin的回答的这个问题

Disclaimer: There is a good reason to not explicitly map Purchases <-> Bonds; shouldn't be relevant to the question, but the background is based on Floremin's answer to this question

谢谢!

推荐答案

LINQ到实体转化LINQ查询到SQL查询,然后将其发送和执行数据库(服务器)。这就是为什么你会得到你的 get_purchases 方法不能被翻译成店表达式(SQL)除外。

LINQ to entities translates LINQ queries into SQL queries which are then sent and executed in the database (server). That's why you get the exception that your get_purchases method cannot be translated into store expression (SQL).

要获得支付了本本超过90,你可以使用LINQ加入运营商:

To get books that were paid more than 90 you can use LINQ Join operator:

var books = from b in dBContext.Books
            join p in dBContext.Purchases on b.isbn equals p.isbn
            where p.price > 90
            select b;

下面是一个伟大的LINQ的资源:的 LINQ 101

Here is a great LINQ resource: LINQ 101

如果你想有EF-样的导航性能像 Book.Purchases 那里是在数据库中没有实际的关系,你必须创建一个将与被初始化自己的数据存储库层的的DbContext 这将在所有的属性和方法中使用。然后你会使用,对于所有的数据访问 - 即你永远不会在你的代码中使用的DbContext 直接。这是大型项目的一个很好的做法,特别是如果你需要实现一些业务规则和数据处理之前被存储在数据库中。查一查库模式,你一定能找到很多资源。

If you want to have EF-like navigation properties like Book.Purchases where there is no actual relation in the database, you'd have to create your own data repository layer that would be initialized with the DbContext which would be used in all properties and methods. Then you would be using that for all data access - i.e. you'd never use DbContext directly in your code. This is a good practice on larger projects, especially if you need to implement some business rules and data manipulation before it gets stored in the database. Look up "repository pattern" and you're sure to find many resources.

这里有一个:的使用与ASP.NET MVC和Entity Framework

这篇关于实体框架:&QUOT;伪造&QUOT;可查询的导航属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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