I would like to set up something like below as it is a cleaner POCO design, but it seems that I can only make this work by creating a UserId property of int instead of the lazily loaded POCO.
[Route("/Accounts", "GET")] //Where I want to be able to do /Accounts?UserId=1234
[Route("/Accounts/{Id}", "GET")]
public class Account
{
public User User {get;set;}
public int Id {get;set;}
...
}
public class User
{
public int Id {get;set;}
...Lazily loaded values
}
Is this the only option?
public class Account
{
public int UserId {get;set;}
public int Id {get;set;}
...
}
Is the Account class your request dto? See the wiki to see how to decorate your request dto with routes, https://github.com/ServiceStack/ServiceStack/wiki/Routing
Related
I am using ASP.NET Identity 2.2.0 with ASP.NET MVC 5.2.3 and Entity Framework 6.1.2.
I added a new property and its corresponding table to my database using ASP.NET Identity with Code First like so:
public class ApplicationUser
{
[ForeignKey("UserTypeId")]
public UserType Type { get; set;}
public int UserTypeId { get; set;}
}
public class UserType
{
[Key]
public int Id { get; set;}
public string Name { get; set; }
}
Now, from some action, when I call:
var user = UserManager.FindByNameAsync(userName);
It does get the user with the correct UserTypeId because that is a primitive, but it does not get the UserType property of the ApplicationUser class.
If I were not using this abstraction, I would either call LoadProperty<T> or the Include method in Entity Framework to include the navigational property or relation named Type (of type UserType) on the ApplicationUser class.
How do I do that with ASP.NET Identity's UserManager? I suspect the only way would be to override this method in my custom UserManager derived class and do it myself?
With Entity Framework lazy loading, you need to ensure that your navigation properties are marked as virtual.
public class ApplicationUser
{
[ForeignKey("UserTypeId")]
public virtual UserType Type { get; set;}
public int UserTypeId { get; set;}
}
Alternatively if you are unable/don't want to use lazy loading, then you can still use your context as you would any other entity:
var user = context.Users.Include(u => u.Type).Single(u => u.UserName == userName);
I'm using EF Code first.
I created two classes. For simplicity, imagine that I have a User table (class) and a FileAttachment table. I want to use the FileAttachment table with many other classes, so that any part of the application that requires having a FileAttachment can reuse that table. The problem is that when EF generates the schema, it creates a Foreign Key in the FileAttachment table back to User table. Is there a way to disable that?
Thanks
You need to build an intermediate class.
public class UserDocument
{
public int Id {get;set;}
public int UserId {get;set;}
public virtual User User {get;set;}
public int FileAttachmentId {get;set;}
public virtual FileAttachment FileAttachment {get;set;}
}
So your user class can now have:
public virtual ICollection<UserDocument> Documents {get;set;}
And in this case, FileAttachment class will not have reference to User.
If you want now to build some other document type, just implement another intermediate type, i.e. imagine you want to have CustomerDocument:
public class CustomerDocument
{
public int Id {get;set;}
public int CustomerId {get;set;}
public virtual Customer Customer {get;set;}
public int FileAttachmentId {get;set;}
public virtual FileAttachment FileAttachment {get;set;}
}
And then your hypothetical Customer class would have:
public virtual ICollection<CustomerDocument> Documents {get;set;}
I have a straight forward scenario
class Person
{
[Required]
public int Age {get;set;}
[Required]
public virtual Pet Pet {get;set;}
}
class Pet
{
...
}
both Person & Pet are mapped in the context. lazy loading is enabled.
If I attempt to update the age of the person I receive a validation error stating Pet is required.
var person = context.People.Find(id)
person.Age = 30;
context.SaveChanges(); //causes validation error.
I wouldn't think I need to load related entities for the context to produce the correct sql statements. Am I missing something, or is this just not possible?
solution
given the limited options EF provides for this I went with disabling validation via an ActionFitler
public class DoNotValidateEntityFrameworkAttribute
: ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
actionContext
.ControllerContext
.Configuration
.DependencyResolver
.GetService<DbContext>()
.Configuration
.ValidateOnSaveEnabled = false;
base.OnActionExecuting(actionContext);
}
}
class MyController : ApiController
{
[DoNotValidateEntityFramework]
public void Put(int id, Model model)
{
...
}
}
One option is to use this instead:
class Person
{
[Required]
public int Age {get;set;}
[Required]
public int PetId { get; set; }
public virtual Pet Pet {get;set;}
}
This will make just FK required but not the entity. Other options is turning validation off because it doesn't support incomplete object graphs:
context.Configuration.ValidateOnSaveEnabled = false;
I have the following classes:
public class Configuration
{
public long Id {get;set;}
public string Name {get;set;}
public Expression Criteria {get;set;}
}
public class Expression
{
public long Id {get;set;}
public string Value {get;set;}
public ICollection<Parameter> Parameters {get;set;}
}
public class Parameter
{
public long Id {get;set;}
public MyType Type {get;set;}
}
public class MyType
{
public long Id {get;set;}
public string Name {get;set;}
}
I am trying to eagerly load the entire configuration object using:
dbContext.Configurations.Select(i => i.Criteria).Include(i => i.Parameters.Select(j => j.Type)).ToList()
I am however getting null for the Parameters property and it is not getting fetched.
What am I doing wrong.
Try this:
dbContext.Configurations.Select(i => i.Criteria).Include("Parameters").Include("Parameters.Type").ToList()
I created classes:
public class Country
{
public long CountryId {get;set;}
public string CountryName {get;set;}
}
public class Profile
{
public long ProfileId {get;set;}
public string ProfileName {get;set;}
public Country Country {get;set;}
}
and configuration for Profile:
public class ProfileConfiguration : EntityConfiguration<Profile>
{
public IlluminatiCoreProfileConfiguration()
{
Relation(p => p.Country);
}
}
Then I create context and run context.CreateDatabase(). New database contains table Profiles with column Country_CountryId. How can I write configuration for changing column name to "CountryId"?
Thanks.
In your POCO for Profile:
public class Profile
{
public long ProfileId {get;set;}
public string ProfileName {get;set;}
[ForeignKey("CountryId")]
public Country Country {get;set;}
}
In your POCO for Country
[Table("Country")]
public class Country
{
[Column(Name = "CountryId")]
public int CountryId {get;set;}
}
This will over write the brain dead Object_Property mapping that EF by default creates. You can specify this on any table / property to override the actual DB column naming conventions.
EDIT:
I guess the namespace for those annotations would be helpful:
using System.ComponentModel.DataAnnotations;