generic class constraints: 2 types - linq

i want to create a generic class that would accept T.
T is an object coming from Entity Framework representing a Table, or a View of that table.
properties on both would be the same.
I would like to create a generic class, that will accept the table or view, and construct a linq query based on the properties.
so i would need to do something like..
class Foo Where T : myTable or T : myView
so that later i could use the strongly typed properties to construct my predicates.
How could i achieve something like this?
the way i construct my query looks something like this:
if (critera.IsTradeDate)
predicate = PredicateUtility.And(predicate, t => t.DateTrade >= critera.FromDate);
the t is the type that needs to be strong, and properties used will be the same on table and view. So in this case, t should represent either my table or my view, to re-use the code, but still leverage entity framework..

Create an interface ITableOrView (or some better name). Apply the interface to both partial classes for your Entities that are the Table or View.
Create your generic class with where T : ITableOrView
Now you can use the interface types.
BUT you can't use interfaces in many places in Entity Framework queries so you'll actually need to delegate that work back to the 'T' class itself.

Related

Entity Framework: Implement interface when generating from database

I'm having a few tables on SQL Server, which have similar structure - int Id and string Value.
This tables linked to main table via foreign key, so I'm wrote a bit of logic for mapping a string values to id's in models in MVC Razor. This feature requires that models used as dictionary implement simple IKeyValue interface with Id and Value, but after updating model from database I can loose interface implementation from models and must write it again.
Any way to automate this?
Are you modifying the auto-generated file? If so, you should not do this, for the exact reason you describe in your question -- it will get overwritten.
All of the classes in the generated file should be partial. You can take advantage of this by creating another class (in a different file, but in the same project), make sure it has the same declaration (and namespace), and have it implement the interface. This way the class will implement the interface, but will not be overwritten the next time you refresh the schema from the database.

linq to sql, how to define DataContext without specifying Table properties

My intent is to create a generic (not in C# meaning) database model for Windows Phone using linq to sql. User of such model should be able to pass an array of his data object types (classes marked with Table attribute) to model's contstructor, and then model should take care about adding related tables to database and provide API for CRUD operations.
But then I've found out that in order to add tables to database, your data context (class inherited from DataContext class) have to declare each table as a property! That's embarrassing. Does this fact mean that my idea is not implementable? Because I obviously cannot add properties to my DataContext-based in the runtime.
So my question is, am I right in my judgments? If yes, are there some workarounds to solve this issue?
Thanks in advance.
EDIT: better question tagging, for somebody finally notice this.
You do not need to use a strongly typed DataContext (a class inheriting from DataContext and declaring properties for each table). You can do something like the following instead
var context = new DataContext("connection string", new AttributeMappingSource());
var table = context.GetTable<T>();
where T is some type marked with the Table attribute.

how to modify collection classes provided by EF after associating one class to another?

I'm new to MVC & EF. I'm developing the MVC project with model first approach. In my project i have different entities like-customer,employee,product,etc. and i created association between them like 1 to many in customer-employee like this. and after creating this association; it is generating navigation property in customer entity i.e, Employees (collection object) for employee entity.
I want to modify this collection class and i want to add some more methods on it. Is it possible? How to do this if possible?
thanks.
The property is generated with ICollection<Employee> type. You can in theory create your own class implementing this interface and initialize the property for example in Employee constructor but the property will still expose the interface. Changing return type of the property requires change in class generator (you should use T4 template which would make this easy task). By changing property's return type to your collection you can lose some EF functionality.

Partial loading of Entity Framework entities and passing them to presentation layer

If I want to select only few columns when retrieving data for an EF entity and cast them to the Entity type, I am not able to do that because it throws an error as mentioned in this post
The entity cannot be constructed in a LINQ to Entities query. I don't want to select all the columns, because I need only few of them. I can use anonymous types, but if I am using repository pattern and want to encapsulate all data access code in repository object and pass strongly typed object collection to the controller (not an anonymous object collection), how can I achieve that? Is the only option to define a DTO object for every subset of the properties for the EF entity? I know there is a risk of losing data with partial loaded entities, but if I am ready to take the risk and want full control over data updates, is that not possible?
for example I would like the "ProductRepository" method signature to be like this
public IEnumerable<Product> GetProducts(int categoryID) //selection of subset of data
and I want to pass this product collection from the controller to the view (in ASP.NET MVC project) and in the view I want to have strongly typed model (with intellisense) object. Is this possible? if not, I may have to reconsider using EF for my project due to this limitation. I am using EF 4.1 version.
Yes the option in this case is special object for each subset of properties you want to select. You can call the object DTO because it is just a result of the projection. This is the correct approach because if your UI doesn't need other properties of entity type it is correct to pass it only specialized ViewModel.
Another more complex (and worse) option is selecting anonymous type inside your Linq-to-entities query, calling ToList and after that construction the real entity type. Partial entity selection is not allowed and projecting to mapped entity types is not allowed as well. That is the reason why you have to use such a cumbersome approach. Example:
// Select anonymous projection
var query = from x in context.Entities
where ...
select new { ... };
// Repopulate entity type
var reultSet = query.ToList().Select(x => new Entity { ... });
Yes, what you want is totally possible using viewmodels instead of entities. Here is example controller code:
var productEntities = productRepos.GetProducts(6);
var productViewModels = Automapper.Mapper
.Map<IEnumerable<ProductViewModel>>(productEntities);
return View(productViewModels);
Your view model will have only the properties it needs for the view. Check out automapper.

LinQ ORM Data Objects and Inheritance

I'm thinking about how to do this, but I have several different shapes of Data in my Database, Articles, NewsItems, etc.
They All have something in common, they all have IDs (in the DB they're named ArticleID, NewsID etc. )
They all have a Title
They all have BodyText.
They all have a Status
They all have a DateAdded
What I'd like to do is standard class inheritance.
I'd like a Master Class (I don't need to write this to the database) called Content with fields like:
ID
Title
SubTitle
BodyText
Status
AddedDate
I'm not sure how I can do this with the ORM. Why I want this is because then I can pass a list of COntent to my UserControl which is responsible for Rendering it. It will only need the information that is common to all objects.
Is this even possible?
This is what Interfaces are for. Have each class implement an IContent interface that contains your Title, BodyText, Status and DateAdded properties. Now you can pass around a collection ( List<IContent> ) around that could containt different types of content.
If you're using LinqToSql you can create partial class files to have the autogenerated classes implement the interface you want.
public partial class SomeContent : IContent
I'm not sure whether you're talking about LINQ to SQL, but there are a few resources online about how to create inheritance with it:
LINQ To SQL Discriminator Column Example - Inheritance Mapping Tutorial
Inheritance in LINQ to SQL Screencast
...and more.
HTH
I found one page that looks like it has something along the lines of what I'm looking for (The last post)... but I'm not sure about using weakly typed objects:
LINQ inheritance

Resources