Using LINQ to query concrete classes stored in base class tables - c#

I'm just starting to get my head around LINQ queries. I've looked at the MSDN page about type relationships, and understand the rudiments of querying. However, I can't find anything that helps me with querying when EF6 (code first) has merged a number of concrete classes into one table based on the base class.
I have a base abstract class declared like this:
public abstract class Product
{
// a whole bunch of fields, properties, and methods
}
and then a bunch of concrete classes declared like this:
public class ProductOption : Product
{
public ProductOption()
{
// A bunch of stuff to set properties in the base class.
}
}
Entity Framework creates a single table called Products that has a column named Differentiator with values identifying the name of the concrete class the particular row holds (e.g. ProductOption). The column does not create a property in Product.
What I would like to do is (following the MSDN example) declare something like:
var queryAllProductOptions = from po in ProductOptions
select po;
I've heard from at least one person that I need to filter instead, looking something like this (luckily we have a property that helps):
var queryAllProductOptions = from po in Products
where po.Category = ProductCategory.Option
select po;
The implications of being able to use the first method are significant. We have a workaround, but it might cause complications in certain instances (though none insurmountable).
Does the first way work, or do we need to filter Products the way the second method outlines?

I think what you have here is TPH inheritance.
Querying types in a TPH mapping are like this :
var query =
from lodge in context.Lodgings.OfType<Resort>()
select lodge;
excerpt coming from programming entity framework page 392
So did you consider the OfType yet ?

Related

Casting to and from Derived Types using LINQ

I'm somewhat new to using LINQ and Entity Framework, and am running into a snag when casting Entity Framework object types to/from objects of a class derived from that object type.
To provide context, I am selecting Survey objects from my Entity Framework DB (records from a Surveys table), for which I have created a derived class that I will actually cast these entity objects to before using them in my application - such that the derived class's signature looks something like:
public sealed class SurveyExtended : Survey
{
public SurveyExtended() : base()
{
// non-base class members initialized here
}
}
And when using LINQ to populate a collection of these objects, I am casting them to the SurveyExtended type using code similar to:
var listOfSurveyExtendedObjects = ( from record in contextFactory.SurveysDbContext.Surveys
select new SurveyExtended()
{
Name = record.Name,
Data = record.Data,
Date = record.Date
}
);
Please note, I know I could use lambda to do the same thing, but I'm just trying to illustrate a concept.
All is well and good, until I actually try and execute DML against SurveysDbContext to do things like UPDATE or DELETE the original record after processing it in my application, such as: contextFactory.SurveysDbContext.Surveys.DeleteObject( surveyExtendedObject );.
Of course this isn't going to work, because I'm manipulating SurveyExtended objects, not the original Survey entity objects, and the ObjectStateManager will throw an InvalidOperationException because the object itself cannot be found. That is to be expected.
I guess what I'm looking for are suggestions and alternative approaches to this scenario. Should I attempt to cast back to Survey objects before trying to DbContext.DeleteObject( record );, or change my approach to this problem entirely? In similar situations, what methods did/do you use, and what benefits/drawbacks do they offer?
The options that come to mind are either cast it back before saving / interacting with EF, or switch to using something like a decorator pattern where the Extended object encapsulates the Survey. Though the second option either means you need to mimic the encapsulated object exposing pass-through accessors (double the code, double the fun) or change referencing code to access SurveyExtended.Survey.Property.

Get all associate/composite objects inside an object (in Abstract way)

Business:
I have a payment system in which payment can be made though GiftCoupon, ClubMembershipCard etc. One payment itself can have multiple payment components
Class:
I have a Payment class. It has payment components like GiftCouponPayment, ClubMembershipCardPayment, CashPayment and so on. Each component type satisfy a common interface IPaymentComponent. I have implemented it using the knowledge about the existing types.
Questions
1) How to implement this function in a abstract way – without knowing what all are the types that exist? That means it need to work for all types that implement IPaymentComponent interface.
2) If it is not possible to achieve it in LINQ to SQL, is it possible in Entity Framework?
3) Is it association / aggregation or composition when LINQ to SQL generate GiftCouponPayment entities inside Payment object?
Note: I am using LINQ to SQL as ORM. GiftCouponPayment and Payment are autogenerated classes and these objects are created by ORM. I have added more functionality to these classes by using partial classes.
Note: In database each PaymentComponent (E.g. GiftCouponPayment) has its own properties (e.g CouponValue,CardValue etc). Hence Table-Per-Hierarchy will not be good. We need separate tables. Is there a solution in that line?
Note: GiftCouponPayment already exist in the database prior to this payment. We need to identify the GiftCouponPayment object by using GiftCouponPaymentID provided by the customer. We just need to update the PaymentID column in this table.
A leaky abstraction refers to any implemented abstraction, intended to reduce (or hide) complexity, where the underlying details are not completely hidden
LINQ to SQL Diagram
REFERENCE:
Entity Framework 4, inheriting vs extending?
How to choose an Inheritance Strategy http://blogs.msdn.com/b/alexj/archive/2009/04/15/tip-12-choosing-an-inheritance-strategy.aspx
Fluent API Samples - http://blogs.msdn.com/b/adonet/archive/2010/12/14/ef-feature-ctp5-fluent-api-samples.aspx
C# CODE
public interface IPaymentComponent
{
int MyID { get; set; }
int MyValue { get; set; }
int GetEffectiveValue();
}
public partial class GiftCouponPayment : IPaymentComponent
{
public int MyID
{
get
{
return this.GiftCouponPaymentID;
}
set
{
this.GiftCouponPaymentID = value;
}
}
public int MyValue
{
get
{
return this.CouponValue;
}
set
{
this.CouponValue = value;
}
}
public int GetEffectiveValue()
{
if (this.CouponNumber < 2000)
{
return 0;
}
return this.CouponValue;
}
}
public partial class Payment
{
public List<IPaymentComponent> AllPaymentComponents()
{
List<IPaymentComponent> allPayComps = new List<IPaymentComponent>();
List<GiftCouponPayment> giftCouponPaymentList = new List<GiftCouponPayment>();
List<CashPayment> cashPaymentList = new List<CashPayment>();
foreach (GiftCouponPayment g in this.GiftCouponPayments)
{
giftCouponPaymentList.Add(g);
allPayComps.Add(g);
}
foreach (CashPayment c in this.CashPayments)
{
cashPaymentList.Add(c);
allPayComps.Add(c);
}
return allPayComps;
}
}
I think you might want to step back from the design for a moment. What I've heard is this:
A payment consists of one or more components, and each component can be one of a variety of types
What it sounds like you need is a Payment table, then a PaymentComponent table with a foreign key relation back to the Payment table. You can then implement inheritance on the PaymentComponent table for your various forms of payment.
You can try to use an abstraction layer or a data acces layer that will be generic of type T. Or at least make the methods generic.
You basically have a few of issues here:
How to model the payment types
Lets assume we want to go at this the classic OOP way:
You need a base class, Payment (or PaymentBase) which is abstract and various class which inherit from it e.g. PaymentInCash, PaymentWithCreditCard and etc.
An alternative could be adding PaymentDetails to Payment and creating a hierarchy of PaymentDetails, if you choose to do this, the replace Payment with PaymentDetails in all the following points.
For payments with multiple methods, you could either:
a. Have a collection of PaymentDetails under a Payment
or
b. Create a type called AggregatePayment which has a list of Payments.
How to map the payment types to tables
Both TPT and TPH are valid here...
For TPT use one table for Payment and one table for each kind of payment.
All the inheriting type's tables PK's should be an FK to the base type's table.
If you have multiple levels of hierarchy, you can use either TPT or TPH on the second (or any other) level if you are using EF.
For TPH use one table with a discriminator column (e.g. PaymentType), and mark each column that is not shared between all entities in the hierarchy as nullable. Do not use the same column for different properties in different entities. In EF, map each entity to the same table with the condition PaymentType = (number goes here) and (column name(s) that should not be null) is not null.
My recommendation is, if you have many narrow types (few properties each) go with TPH, if you have a few wide types go with TPT.
Which design pattern / code technique to use for payment algorithm
You have more options here:
a. Use partial classes and put an abstract ProcessPayment() method on the base class and override in the inheriting classes.
b. Use a base PaymentProcessor class and a specific PaymentProcessor per payment type e.g. PaymentInCashProcessor. In this method you can use reflection to load the correct PaymentProcessor type by either storing a dictionay or better yet, using generics:
abstract class PaymentProcessor
{
}
abstract class PaymentProcessor<TPayment> : PaymentProcessor
where TPayment : class, Payment
{
}
class PaymentInCashProcessor : PaymentProcessor<PaymentInCash>
{
}
// Use reflection to find types that inherits from PaymentProcessor<PaymentInCash>
// create an instance of the type you found
// then cast the instance to PaymentProcessor<PaymentInCash> to use
If you design your EF model you can use the abstract property on a base class called payment. And let inherit all your payment types that class:
Payment will have all common properties, and every specific type can have their own properties.
If you have this kind of model you can just query for payments.
This returns all objects that inherit of the payment type:
var allPayments = objectContext.Payments;

Map Multiple Tables to One Table Produces Foreign Key Column for each in Fluent NHibernate

I want to Point 3 tables Property, Business, Automobile to single Table named Utility.
Using Fluent NHibernate, I followed
public UtilityMap()
{
// some Mappings
References<Automobile>(x => x.Automobile, "LeaseRefId").Cascade.None();
References<Business>(x => x.Business, "LeaseRefId").Cascade.None();
References<Property>(x => x.Property, "LeaseRefId").Cascade.None();
}
and in Each table that maps to the Utility, I followed
public AutomobileMap()
{
//Some Mappings
HasOne<Utility>(x => x.CommonDatas)
.Cascade.All();
}
"I want to have a single column in Utility Table that can store the
references of all the three (Automobile, Business, Property) tables.
But fluent Nhibernate is creating foreing key columns for each of the
table referenced. I want to avoid this."
Is there any way to achieve this??
Please suggest
Thanks in Advance.
For this to work as you expect, you'll need to have a base class for Automobile, Business and Property classes. Let's call it LeaseSubject. Presumably, you already have something like that in your domain model.
Your Utility class should have only one property, instead of three you have now:
public virtual LeaseSubject LeaseSubject { get; set; }
This way you not only have easier mapping, but also promote the maintainability of your code. What if at some later time you decide to have one more lease subject, i.e. Yacht? Instead of adding another Yacht property to your Utility class, you just need to inherit from LeaseSubject, and it could be contained within the LeaseSubject property on Utility class.
Now you could map your Utility simply as:
public UtilityMap()
{
// Other mappings...
References(x => x.LeaseSubject, "LeaseRefId");
}
For mapping Automobile, Business and Property classes, you would use one of three available NHibernate inheritance strategies:
table per class hierarchy
table per subclass
table per concrete class
For FluentNHibernate inheritance mapping, take a look here.
Since you already have separate tables, I believe the correct strategy for your case would be Table per concrete class. You can find some more info in this article.

Why can't NHibernate use Identity in union-subclass Table per Concrete Class mapping?

Several sources state that NHibernate can not use identity with table per concrete class and union-subclasses. Is this true, and what is the exact reason behind this ?
It's simple. The POID must be unique across all instances of a root entity type.
Consider the following example:
abstract class Vehicle { ... }
class Car : Vehicle { ... }
class Truck : Vehicle { ... }
If you were to retrieve a Vehicle whose concrete type you don't know:
var carOrTruck = session.Get<Vehicle>(vehicleId);
...and there were both a Car and a Truck with that Id (which is possible with identity), which one would NHibernate return? (there are more complex cases, but this illustrates one possible issue)
Therefore, for table-per-concrete-class (a pretty bad strategy if you ask me), NHibernate needs a generator that guarantees uniqueness across subclasses.
Why do you say so? I think I had several scenarios like that. Also this blog entry states the same.
To sum up comments below:
as in the example that Ayende has, if you query for all root types (so "Select Party") you can get duplicates for ID. That fact along with UNION characteristic (returns only distinct records) could give you unexpected results (missing records). That's why you cannot use identity but rather hilo which allows nhibernate to avoid duplicates.

Adding behavior to LINQ to Entities models

What's the preferred approach when using L2E to add behavior to the objects in the data model?
Having a wrapper class that implements the behavior you need with only the data you need
using (var dbh = new ffEntities())
{
var query = from feed in dbh.feeds select
new FFFeed(feed.name, new Uri(feed.uri), feed.refresh);
return query.ToList();
}
//Later in a separate place, not even in the same class
foreach (FFeed feed in feedList) { feed.doX(); }
Using directly the data model instances and have a method that operates over the IEnumerable of those instances
using (var dbh = new ffEntities())
{
var query = from feed in dbh.feeds select feed;
return query.ToList();
}
//Later in a separate place, not even in the same class
foreach (feeds feed in feedList) { doX(feed); }
Using extension methods on the data model class so it ends up having the extra methods the wrapper would have.
public static class dataModelExtensions {
public static void doX(this feeds source) {
//do X
}
}
//Later in a separate place, not even in the same class
foreach (feeds feed in feedList) { feed.doX(); }
Which one is best? I tend to favor the last approach as it's clean, doesn't interfere with the CRUD facilities (i can just use it to insert/update/delete directly, no need to wrap things back), but I wonder if there's a downside I haven't seen.
Is there a fourth approach? I fail at grasping LINQ's philosophy a bit, especially regarding LINQ to Entities.
The Entity classes are partial classes as far as i know, so you can add another file extending them directly using the partial keyword.
Else, i usually have a wrapper class, i.e. my ViewModel (i'm using WPF with MVVM). I also have some generic Helper classes with fluent interfaces that i use to add specific query filters to my ViewModel.
I think it's a mistake to put behaviors on entity types at all.
The Entity Framework is based around the Entity Data Model, described by one of its architects as "very close to the object data model of .NET, modulo the behaviors." Put another way, your entity model is designed to map relational data into object space, but it should not be extended with methods. Save your methods for business types.
Unlike some other ORMs, you are not stuck with whatever object type comes out of the black box. You can project to nearly any type with LINQ, even if it is shaped differently than your entity types. So use entity types for mapping only, not for business code, data transfer, or presentation models.
Entity types are declared partial when code is generated. This leads some developers to attempt to extend them into business types. This is a mistake. Indeed, it is rarely a good idea to extend entity types. The properties created within your entity model can be queried in LINQ to Entities; properties or methods you add to the partial class cannot be included in a query.
Consider these examples of a business method:
public Decimal CalculateEarnings(Guid id)
{
var timeRecord = (from tr in Context.TimeRecords
.Include(“Employee.Person”)
.Include(“Job.Steps”)
.Include(“TheWorld.And.ItsDog”)
where tr.Id = id
select tr).First();
// Calculate has deep knowledge of entity model
return EarningsHelpers.Calculate(timeRecord);
}
What's wrong with this method? The generated SQL is going to be ferociously complex, because we have asked the Entity Framework to materialize instances of entire objects merely to get at the minority of properties required by the Calculate method. The code is also fragile. Changing the model will not only break the eager loading (via the Include calls), but will also break the Calculate method.
The Single Responsibility Principle states that a class should have only one reason to change. In the example shown on the screen, the EarningsHelpers type has the responsibility both of actually calculating earnings and of keeping up-to-date with changes to the entity model. The first responsibility seems correct, the second doesn't sound right. Let's see if we can fix that.
public Decimal CalculateEarnings(Guid id)
{
var timeData = from tr in Context.TimeRecords
where tr.Id = id
select new EarningsCalculationContext
{
Salary = tr.Employee.Salary,
StepRates = from s in tr.Job.Steps
select s.Rate,
TotalHours = tr.Stop – tr.Start
}.First();
// Calculate has no knowledge of entity model
return EarningsHelpers.Calculate(timeData);
}
In the next example, I have rewritten the LINQ query to pick out only the bits of information required by the Calculate method, and project that information onto a type which rolls up the arguments for the Calculate method. If writing a new type just to pass arguments to a method seemed like too much work, I could have also projected onto an anonymous type, and passed Salary, StepRates, and TotalHours as individual arguments. But either way, we have fixed the dependency of EarningsHelpers on the entity model, and as a free bonus we've gotten more efficient SQL, as well.
You might look at this code and wonder what would happen if the Job property of TimeRecord where nullable. Wouldn't I get a null reference exception?
No, I would not. This code will not be compiled and executed as IL; it will be translated to SQL. LINQ to Entities coalesces null references. In the example query shown on the screen, StepRates would simply return null if Job was null. You can think of this as being identical to lazy loading, except without the extra database queries. The code says, "If there is a job, then load the rates from its steps."
An additional benefit of this kind of architecture is that it makes unit testing of the Web assembly very easy. Unit tests should not access a database, generally speaking (put another way, tests which do access a database are integration tests rather than unit tests). It's quite easy to write a mock repository which returns arrays of objects as Queryables rather than actually going to the Entity Framework.

Categories

Resources