I have searched every way I can think of for the answer to this, so forgive me if I have overlooked a post...
I have a project containing model classes that I want to remain database-ignorant (pretend someone handed me the code and said "you're not allowed to modify one character of these classes"). I want to persist these to SQL Server using Entity Framework. So far, I have been able to use the fluent API to map anything that EF couldn't determine logically. But I have hit a block with the following:
public class PhotoPost {
// mapped as Key with fluent API - comes from blog provider
public string PostID { get; set; }
public string Caption { get; set; }
public Collection<Photo> Photos { get; set; }
}
public class Photo {
public string Url { get; set; }
public Image LoadImage() { … }
}
I have a class, PhotoPost, which represents a type of Post on a Blog. The PhotoPost instance has a collection of objects of type Photo, all of which need to be persisted to the database. My problem is that the Photo doesn't really have a primary key. Blog provider doesn't guarantee the Url will not change, and I can't touch this code to add an arbitrary ID. Furthermore, I don't really want an ID. The code that is going to interact with these objects shouldn't/won't know whether these objects came from the blog's API or from a local database (or XML, ...), so I don't really want to clutter up my code with boilerplate in subclassing these objects in another project just to add IDs everywhere (and constructors to create subclasses with IDs from parent classes without, as above) to make EF happy.
Is subclassing to add IDs my only option, or is there a way that I can meet in the middle, between "entity" and "complex type"? (From what I understand, complex types must be one-to-one with their parent entities.)
Related
So if I have the following entity:
public class Guest
{
public int GuestId { get; set; }
public bool HasCheckedIn { get; set; }
// child/related entities
public Person Person { get; set; }
public Address Address { get; set; }
public Phone Phone { get; set; }
}
Please forgive/correct me if some of the terminology I use is not correct...
Assume we have turned off Navigation Properties which would automatically populate the child entities such as Person and Address.
If my website is calling the WebApi for specific data, sometimes it might need the 'full' Guest object with all of the child entities, in which case it might call the appropriate method in the Business Layer to backfill the object. In other cases, to keep the request light we might just want a 'shell' or 'brief' of the Guest with just the basic data that the underlying table would hold such as HasCheckedIn and all the child entities to just be null.
So what is the suggested approach here for the Api Controller? Should there just be one Persons Controller who's Get method is really a proxy to the GetFull method in the BLL Person class and then have a separate PersonsBrief Controller who's Get method is really a proxy to the GetBrief method in the BLL Person class? Or should this be one method in the Persons Controller which takes in a boolean for IsBrief or something?
Both approaches have merit but it may actually be clearer to separate the summary and details into separate resources. It seems like your use cases between the two variations are distinct, which to me suggests that you should separate your resources accordingly. In other words, implement two separate controller methods, one for "guest details" and another for "guest summary".
I am EF new learner, i have some questions to ask:
1.
I don't understand what does virtual mean in for example one to many, i give an example:
one question can have many options for e.g.
public class Question
{
public int QuestionId { get; set; }
public string Title { get; set; }
public virtual List<Option> Options { get; set; }
}
public class Option
{
public int OptionId { get; set; }
public string OptionText { get; set; }
public virtual Question Question { get; set; }
}
but what does the "2" virtual mean, because if i delete the virtual in this line:
public virtual List<Option> Options { get; set; }, i didn't find any differences, it works well as one to many, so can you explain me very clearly and easily what the 2 virtual mean, if it's override, override what?
2.
I don't know when we should use API fluent, for e.g. the previous one to many ex. without api fluent, it's still a one to many Relationship, so please just tell me when we should use it ? in which occasions for example.
3.
in the API fluent, i know "withmany" and "hasmany" together, they mean "many to many", and what's "withrequired? isoptional? "
I think I can answer following points:
EF define all navigation property virtual, so that EF will at runtime create a new class (dynamic proxy) derived from your Brand class and use it instead. This new dynamically created class contains logic to load navigation property when accessed for the first time. This feature is called lazy loading (or better transparent lazy loading).
See the following link for more detail
Entity Framework 4.1 Virtual Properties
2.When to use fluent API
When working with Code First, you define your model by defining your domain CLR classes. By default, the Entity Framework uses the Code First conventions to map your classes to the database schema. If you use the Code First naming conventions, in most cases you can rely on Code First to set up relationships between your tables based on the foreign keys and navigation properties that you define on the classes. If you do not follow the conventions when defining your classes, or if you want to change the way the conventions work, you can use the fluent API or data annotations to configure your classes so Code First can map the relationships between your tables.
http://msdn.microsoft.com/en-us/data/jj591620.aspx
3.See the following link to know What is .WithRequired and .WithOptional options
What part does the .WithRequired play in an EF Fluent API?
This is a design problem specific to a Web API project I'm working on, but it might be a question that's general to REST principles. It's also possible I'm completely overthinking this.
I have a class in Entity Framework that has a child collection of another class:
public abstract class Tracker
{
[Key]
public int ID { get; set; }
[MaxLength(50)]
public string Name { get; set; }
public virtual ICollection<Unit> Units { get; set; }
}
The Unit class looks like this:
public class Unit
{
[Key]
public int ID { get; set; }
[MaxLength(50)]
public string Name { get; set; }
}
I'm working on a Web API that will GET a list of trackers, and GET a list of available units, then add a particular unit to a tracker's list of units. Trackers and Units have their own API controllers and repositories and I'm trying to figure out how to modify them to support creating this association, and what the request would look like.
Is it appropriate to update the Tracker endpoint (/Trackers/1) via PUT to add a new Unit to the list, maybe along with the existing Units? How would I handle that on the back end? I think one of the mental hurdles I have with the PUT approach is - would I include the entire child object in the request body collection property? It wouldn't make sense to, but I'm not sure how it would work otherwise. The assumption (in my case) would be that the Unit being added to the Trackers list would be one that already exists and we're just creating the association. Should I maybe use DTOs for both of these to accomplish this more simply and map them accordingly?
Or would it make more sense to create some new joint DTO like "TrackerUnit" with a corresponding endpoint that I can add new associations to by POSTing to that endpoint (POST /TrackerUnits), then handle the processing in a new controller for it? I would think it would also need to support a DELETE to remove the items. I'm not crazy about this approach since this endpoint wouldn't correspond to any actual resources in my system, but just be used for mapping these associations.
How about creating an endpoint:
/Trackers/{id}/units
and then you can Post a Unit to this endpoint to associate with the Tracker identified by the {id}, or similarly:
DELETE /Trackers/{id}/Units/{unitid}
to remove a Unit.
Is it possible to have Code First data classes declared with internal access as shown:
internal class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
I have a requirement that classes and its properties should not be visible outside of the assembly.
As long as your DbContext derived class that exposes your class to EF is in the same assembly, you should be able to. I don't happen to design my apps that way as I prefer more separation. But the context should be able to build the model and it should be able to interact with the classes (e.g. execute queries, save changes etc) if they are in the same assembly since it will have access to the internal class. Even with the various odd things we tried and wrote about in the Code First book, I never happened to try this particular scenario.
I want a list of different (derived) object types working with the Default Modelbinder in Asp.net MVC 2.
I have the following ViewModel:
public class ItemFormModel
{
[Required(ErrorMessage = "Required Field")]
public string Name { get; set; }
public string Description { get; set; }
[ScaffoldColumn(true)]
//public List<Core.Object> Objects { get; set; }
public ArrayList Objects { get; set; }
}
And the list contains objects of diffent derived types, e.g.
public class TextObject : Core.Object
{
public string Text { get; set; }
}
public class BoolObject : Core.Object
{
public bool Value { get; set; }
}
It doesn't matter if I use the List or the ArrayList implementation, everything get's nicely scaffolded in the form, but the modelbinder doesn't resolve the derived object type properties for me when posting back to the ActionResult.
What could be a good solution for the Viewmodel structure to get a list of different object types handled? Having an extra list for every object type (e.g. List, List etc.) seems to be not a good solution for me, since this is a lot of overhead both in building the viewmodel and mapping it back to the domain model.
Thinking about the other approach of binding all properties in a custom model binder, how can I make use the data annotations approach here (validating required attributes etc.) without a lot of overhead?
Check out the Derived Type ModelBinder in MvcContrib. This allows you to modelbind to derived types through the process of 'typestamping' - which is handled automatically for you when using the RenderTypedPartial(...) helper. MvcContrib partials maintain binding state across partials so the Name/Id prefixes are properly maintained on a deep object graph. If you use other mechanisms like templates, then you'll need to handle the typestamping yourself. This is explained in the documentation page.
Getting back to your questions and how the derived types are resolved with the ModelBinder, you can register the derived type variations with attributes in a mechanism similar to the WCF KnownTypeAttribute or you can do the registration on startup. Either way, these variations are registered once and held onto for performance considerations.
The model binder also solves this problem in a way that does not interfere with data annotation/validation attributes. They will work as you expect them in any other scenario.