2

我想知道我是否可以在以下方面获得一些帮助。我正在使用 EF 检索如下数据集。

var booking = this.GetDbSet<Booking>().Include(c => c.BookingProducts.Select(d => d.Product.PrinterProducts.Select(e => e.ProductPrices))).Single(c => c.BookingId == bookingId)

在 PrinterProduct 中有一个外键 PrinterId 用于附加实体打印机。对于预订实体,我还有 PrinterId 也通过外键链接到附加实体打印机。

我希望做的是只检索与预订实体中保存的 PrinterId 相关的 PrinterProduct,而不是我的代码中的所有 PrinterProducts。我曾尝试使用 Join,但已将自己束手无策!

感谢您的帮助!

编辑:

对象结构:

public class Booking
{
    public Guid BookingId { get; set; }
    public string BookingName { get; set; }
    public Printer Printer { get; set; }
    public IEnumerable<BookingProduct> BookingProducts { get; set; }
}

public class BookingProduct
{
    public int BookingProductId { get; set; }
    public Booking Booking { get; set; }
    public Product Product { get; set; }
}

public class Product
{
    public int ProductId { get; set; }
    public string ProductName { get; set; }
    public IEnumerable<PrinterProduct> PrinterProducts { get; set; }
}

public class PrinterProduct
{
    public int PrinterProductId { get; set; }
    public Product Product { get; set; }
    public Printer Printer { get; set; }
    public IEnumerable<ProductPrice> ProductPrices { get; set; }
}

public class ProductPrice
{
    public int ProductPriceId { get; set; }
    public PrinterProduct PrinterProduct { get; set; }
    public decimal Price { get; set; }
}

public class Printer
{
    public int PrinterId { get; set; }
    public string PrinterName { get; set; }   
    public IEnumerable<Booking> Bookings { get; set; }
    public IEnumerable<PrinterProduct> PrinterProducts { get; set; } 
}
4

2 回答 2

1

如果您已设置导航属性,则只需浏览到它:

var myBooking = ... //A single Booking, don't know how you retrieve it in your case.

var myPrinter = myBooking.Printer; //the Printer that is related to the Booking.

var myPrintproducts = myPrinter.PrintProducts; //The products that are related to the printer.

You don't need to keep nesting select statements, that only creates unnecessary confusion and overhead cost. Keep in mind that you need to do this while in scope of the db context. Every time you try to access a property, EF will fill in the needed variables from the database. As long as there is an open db connection, it works.

Edit

If you really need to optimize this, you can use a Select statement. But you only need a single one. For example:

var myPrintproducts = db.Bookings.Single( x => x.ID == some_id_variable ).Select( x => x.Printer.PrintProducts);

But unless you have a very strict performance requirement, it seems better for code readability to just browse to it.

于 2013-08-21T13:27:22.910 回答
1

Given the newly added class structures in your question, I hope I can clear it up now.

From what I see, Bookings and Products have a many-to-many relation (where BookingProduct is used as the connection). The same is true for Product and Printer (where PrinterProduct is used as the connection). From what I understand, you are trying to get from a singular Booking item to a singular PrinterProduct. I don't see any efficient way to do this without introducing the possibility of inconsistency with your data. You're expecting some Lists to return you one result. If it's only one result, why is it a List in the first place?

  • You have a single Booking. You take its BookingProducts. Now you have many items.
  • You take the Product from each individual BookingProduct. If all BookingProducts have the same product, you're in luck and will only have a List<Product> with a single Product in it. However, there is nothing stopping the system from return many different products, so we are to assume that you now hold a List of several Products
  • From each Product in the list, you now take all of its PrinterProducts. You now hold many PrinterProducts of many Products.

As you see, you end up with a whole list of items, not just the singular entity you're expecting.

Bookings, Products and Printers are all connected to eachother individually, like a triangle. I have seen scenarios where that is correct, but nine times out of ten, this is not what you want; and only leads to possible data inconsistency. Look at it this way: Is it ever possible for the Product to have a Printer other than the Printer that is already related to the Booking? If not, then why would you have two relations? This only introduces the possibility that Booking.Printer is not the same as PrinterProduct.Printer.

Your relational model is set up to yield many results, but I think you expect a single result in some places. I would suggest taking another look at your data model because it does not reflect the types of operation you wish to perform on it. Change the many-to-many relations to one-to-many where applicable, and you should be able to traverse your data model in a more logical fashion, akin to the answer I provided in my previous answer.

于 2013-08-22T08:49:43.040 回答