实体框架:自定义连接表多对多?

时间:2015-07-22 21:30:48

标签: c# sql-server entity-framework asp.net-web-api asp.net-web-api2

我有一个相当简单的Web API 2.2(EF6)设置,我有用户和首选项。用户可以有很多首选项,而首选项可以有很多用户,所以我有一个名为UserPreferences的连接表。以下是这些表格:

CREATE TABLE [dbo].[Users](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [FirstName] [varchar](50) NULL,
    [LastName] [varchar](50) NULL,
    [Email] [varchar](50) NULL)

CREATE TABLE [dbo].[Preferences](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](50) NULL,
    [PossibleValues] [nvarchar](250) NULL)

CREATE TABLE [dbo].[UserPreferences](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [PreferenceId] [int] NOT NULL,
    [UserId] [int] NOT NULL,
    [Value] [nvarchar](50) NULL)

如您所见,Preference有一个可能的值列表(逗号分隔),UserPreference有一个Value,它应该是User选择的值。因此,例如,如果首选项的PossibleValues为“蓝色,绿色,红色,白色”,则UserPreference的值可能为“蓝色”。从我理解的方式来看,这种类型的关系是多对多的,但由于我在连接表(Value)中添加了另一个字段,因此实体框架无法将其作为多对多处理。 According to this question's answer,我必须为此创建两个一对多的关系。所以我遵循了那篇文章的建议:

public partial class User
{
    public User()
    {
        Preferences = new HashSet<UserPreference>();
    }
    public int Id { get; set; }
    [Required]
    public string FirstName { get; set; }
    [Required]
    public string LastName { get; set; }
    [Required]
    public string Email { get; set; }

    public virtual ICollection<UserPreference> Preferences { get; set; }
}

public partial class Preference
{
    public Preference()
    {
        Users = new HashSet<UserPreference>();
    }
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    [Required]
    public string PossibleValues { get; set; }
    public virtual ICollection<UserPreference> Users { get; set; }
}

public partial class UserPreference
{
    public int Id { get; set; }

    [Key,Column(Order = 0)]
    public int UserId { get; set; }
    [Key, Column(Order = 1)]
    public int PreferenceId { get; set; }
    public virtual User User { get; set; }
    public virtual Preference Preference { get; set; }
    public string Value { get; set; }
}

我认为看起来是正确的,但是当我在UsersController中使用这样的Controller方法查询服务时:

// GET: odata/Users(5)/Preferences
[EnableQuery]
public IQueryable<UserPreference> GetPreferences([FromODataUri] int key)
{
    return _db.Users.Where(m => m.Id == key).SelectMany(m => m.Preferences);
}

我得到一个异常,说明“无效的对象名称:'dbo.UserPreferences'。”

  "message": "Invalid object name 'dbo.UserPreferences'.",
  "type": "System.Data.SqlClient.SqlException",

我明显有表UserPreferences,所以我只能假设它看起来不像EF预期的那样,但我不知道我应该做些什么来让它工作。我不需要为偏好设置获得用户列表,但我确实需要获得用户的偏好列表,而我无法让它工作。

1 个答案:

答案 0 :(得分:0)

删除

public int Id { get; set; }

来自UserPreference类的

我的代码:

public class AgreementCourse
{
    [Key, Column(Order = 0)]
    [ForeignKey("Agreement")]
    public int AgreementId { get; set; }
    public virtual Agreement Agreement { get; set; }

    [Key, Column(Order = 1)]
    [ForeignKey("Course")]
    public int CourseId { get; set; }
    public virtual Course Course { get; set; }

    public CourseTypeEnum CourseType { get; set; }
}