MSDN >
Home page del forum
>
ADO.NET Entity Framework and LINQ to Entities
>
Business entity transferred between layers
Business entity transferred between layers
- Hi
I am now trying to migrate my knowledge from LINQ to SQL to the Entity Framework.
One of the main questions I have is the following.
In my sample code I am using the Northwind database.
I would like to transfer to the UI a business object which is a customer with the ID 'ALFKI'.
I would also like to transfer in the same business object all those related 'orders' which happened after 1998-01-01.
One more important thing is that the UI should only see the ID and contact name for the customer,
and he/she should only see the shipcity for the orders of the actual customer.
Below is my try.
The problem is with it that now the UI can see all fields for the customer, and all fields for the related orders.
Another problem is that I am not sure whether 'Attach' is the proper method to use and I am not sure whether
the EF-designer-generated Customer object is which I have to transfer between the app layers.
Thanks for any links or code fragments.Customer customer = null; using (NorthwindEntities dc = new NorthwindEntities()) { customer = (from customers in dc.CustomerSet where customers.CustomerID=="ALFKI" select customers).FirstOrDefault(); customer.Orders.Attach( from orders in dc.OrderSet where orders.OrderDate.HasValue && orders.OrderDate.Value.CompareTo(new DateTime(1998, 1, 1)) > 0 && orders.Customers.CustomerID == "ALFKI" select orders); } foreach (Order order in from orders in customer.Orders orderby orders.OrderDate select orders) { Console.WriteLine(order.OrderDate.ToString() + " " + order.ShipCity + " " + order.Customers.CustomerID); } Console.ReadLine();
Tutte le risposte
- Hi,
As for getting the Orders, you're code can be changed to:
orders = customer.Orders.CreateObjectQuery().Where(o=>o.OrderDate != null && o.OrderDate.Value > new DateTime(1998,1,1)).ToList();
This will extract the orders of the customer which apply to you condition, but will not add them to the Orders collection of the specific customer.
As for your requirement to see only some of the fields of the entity, this will make you change your query and get an anonymous type:
var shortDataOfCustomer = (
from c in dc.CustomerSet
where c.CustomerID == "ALFKI"
select new {c.CustomerID, c.CustomerName}).FirstOrDefault();
If you want to return Customer objects and not anonymous types, you can change the new {} to new Customer() {CustomerID = c.CustomerID, CustomerName=c.CustomerName}
of course in this case the entities won't be a part of the ObjectStateManager (meaning the won't be tracked for changes).
- Thanks for your answer.
You are right that I could have written the dates comparison simpler - now I corrected this.
For hiding specifig table fields data from the user I found that I would set the actual entity fields to internal (from public).
Customer customer = null; using (NorthwindEntities dc = new NorthwindEntities()) { customer = (from customers in dc.CustomerSet where customers.CustomerID=="ALFKI" select customers).FirstOrDefault(); customer.Orders.Attach( from orders in dc.OrderSet where orders.OrderDate > new DateTime(1998, 1, 1)&& orders.Customer.CustomerID == "ALFKI" select orders); } foreach (Order order in from orders in customer.Orders orderby orders.OrderDate select orders) { Console.WriteLine(order.OrderDate.ToString() + " " + order.ShipCity + " " + order.Customer.CustomerID); } Console.ReadLine();<br/>
I still have these two remaining questions:
1)
Is Attach the proper method for transferring entities with some specific relations?
2)
How can I update data after the UI changes it?
Updating data only works if the ObjectContext is not disposed.
But when my business logic component recieves a modified Customer entity from the UI, I couldn't find the proper method to save changes.
I tried these two (I added the related error messages):
The object cannot be added to the ObjectStateManager because it already has an EntityKey. Use ObjectContext.Attach to attach an object that has an existing key.using (NorthwindEntities dc = new NorthwindEntities()) { dc.AddToCustomerSet(customer); dc.SaveChanges(); }<br/>
An entity object cannot be referenced by multiple instances of IEntityChangeTracker.using (NorthwindEntities dc = new NorthwindEntities()) { dc.Attach(customer); dc.SaveChanges(); }
Thanks.

