`Only primitive types or enumeration are supported

2019-07-27 08:16发布

问题:

My first question on stackoverflow.com! Wish me luck explaining :)

I am trying to seed a development database with some test data, requiring matching on two fields, and encountered the issue solved here How to seed data with AddOrUpdate with a complex key in EF 4.3

I get the Only primitive types or enumeration types are supported in this context. error as mentioned in the comments by lukyer.

However, despite adding foreign key attributes, and required attributes to the properties in the model as he suggested, I can find no obvious way to clear the error.

Any ideas on how to seed the database successfully would be gratefully received.

The important parts of the model are as follows:

public class User {
    public string ID { get; set; }
    public string Email {get; set; }
}

public class Institution {
    public Guid ID { get; set;}
    public string Name {get; set; }
}

public class UserInstitutionAssociation {
    public Guid ID { get; set; }
    public virtual User User { get; set; }
    public virtual Institution Institution {get; set;}
}

And then the code to migrate from configuration.cs adds a user (jamesbond@mi5.com) and an institution (Top Secret Establishment). It then attempts to add an association between the user and the establishment, for which it should be added only if an association between these two does not already exist.

//Add User to Database
context.Users.AddOrUpdate(u => u.Email,
    new User {
        Email = "jamesbond@mi5.com"
    });
context.SaveContext();

//Add Institution to Database
context.Institutions.AddOrUpdate(u => u.Name,
    new Institution {
        Name = "Top Secret Establishment"
    });
context.SaveContext();

//Add Association between User and Institution
context.InstitutionUserAssociations.AddOrUpdate(u => new { u.User, u.Institution },
    new InstitutionUserAssociation
    {
        User = context.Users.Single(x => x.Email=="jamesbond@mi5.com"),
        Institution = context.Institutions.Single(x => x.Name=="Top Secret Establishment")
    }
);
context.SaveContext();

I have tried changing the model in a number of ways as I understand Lukyer to have suggested, including all solutions described here How Should I Declare Foreign Key Relationships Using Code First Entity Framework (4.1) in MVC3?

In short, I have tried all combinations of the following without success:

public class UserInstitutionAssociation {
    public Guid ID { get; set; }
    [Required]
    [ForeignKey("UserID")]
    public virtual User User { get; set; }
    [Required]
    [ForeignKey("InstitutionID")]
    public virtual Institution Institution {get; set;}
}

and

public class UserInstitutionAssociation {
    public Guid ID { get; set; }
    [Required]
    [ForeignKey("User")]
    public string UserID {get; set; }
    public virtual User User { get; set; }

    [Required]
    [ForeignKey("Institution")]
    public Guid InstitutionID { get; set; }
    public virtual Institution Institution {get; set;}
}

回答1:

Solved. Occurred because of the classes that I included as part of the LINQ query. You can't use x => new { x.User, x.Institution} because x.User and x.Institution are both complex classes. Instead, these need to be primitive base types (such as string or Guid). It was changed in this way AddOrUpdate(x => new {x.UserID, x.InstitutionID}, Associations). The model then needed to be changed so it included properties called UserID and InstitutionID that could be queried by LINQ.

I adjusted the UserInstitutionAssociation code as follows so it included properties called UserID and InstitutionID as well as the User and I:

public class UserInstitutionAssociation {
    public Guid ID { get; set; }

    [Required]
    [ForeignKey("User")]
    public string UserID {get; set; }
    public virtual User User { get; set; }

    [Required]
    [ForeignKey("Institution")]
    public Guid InstitutionID { get; set; }
    public virtual Institution Institution {get; set;}
}

Then adjust the AddOrUpdate call as follows:

//Add Association between User and Institution
context.InstitutionUserAssociations.AddOrUpdate(u => new { u.UserID, u.InstitutionID },
    new InstitutionUserAssociation
    {
        User = context.Users.Single(x => x.Email=="jamesbond@mi5.com"),
        Institution = context.Institutions.Single(x => x.Name=="Top Secret Establishment")
    }
);