将多个表关系映射到一个表关系以查看

时间:2016-04-15 19:27:14

标签: c# sql asp.net asp.net-mvc razor

我正在尝试将多对一关系映射到一起。我觉得我很亲密,但不是那么。

我有这个传感器表:

SensorId
FK_LocationId
Name
etc...

其中包含Data表中的许多数据记录。

DataId
FK_SensorId
Time
Value

我正在尝试为此创建一个模型。

public class DataSensor
{
    public int Id { get; set; }
    public int DataNodeId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public bool active;
    public bool alarm;
}

public class GatheredData
{
    public int Id { get; set; }
    public int DataSensorId { get; set; }
    public DateTime Time { get; set; }
    public float value { get; set; }

    [ForeignKey("DataSensorId")]
    public virtual DataSensor datasensor { get; set; }
}

实际上应该是另一种方式,至少在我看来。传感器将保持List<Data>但传感器中没有FK链接的位置。 Data记录仅通过该传感器的FK映射到传感器。

我在这里面临的问题是,我现在可以看到这一行:

@model IEnumerable<DataVisualization.Models.Data>

而不是循环我的传感器来显示信息,然后显示数据(最终是图表)。我必须循环所有数据,以某种方式组织它我想要的,然后显示它。所以我仍然需要:

@model IEnumerable<DataVisualization.Models.DataSensor>

但这并不能让我访问数据,因为DataDataSensor不会暴露任何此类数据。所以我想到了一些将它们映射在一起的类:

public class DataViewModel
{
    public DataSensor dataSensor { get; set; }
    public List<GatheredData> gatheredData { get; set; }
}

我的观点需要:

@model IEnumerable<DataVisualization.Models.DataViewModel>

这似乎是一种优雅的方式,但我无法使其发挥作用。可能因为这需要public DbSet<DataViewModel> dataViewModel { get; set; }中的DbContext,这会在我的数据库中产生一个尴尬的表。

因此,任何有关如何创建模型,在Controller中使用它并在视图中显示模型的帮助都将非常感激。

修改

这个模型怎么样,所以我可以访问与此相关的数据?

public class DataSensor
{
    [Key]
    public int Id { get; set; }
    public int DataNodeId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public bool active;
    public bool alarm;

    public virtual ICollection<DataSensor> Data { get; set; }
}

但是,这会在数据库表中创建一个列DataSensor_Id。这显然是不可取的,因为那时它将是一对一的。

1 个答案:

答案 0 :(得分:0)

我将在下面留下我的另一个答案,因为它仍然提供有价值的信息。

这就是如何完成从数据库中提取数据以进行显示的方法。您正在使用数据库第一种方法。我建议创建一个新项目来测试它,并习惯于正在发生的事情。现在,您将要转到功能区中的工具并选择连接到数据库。输入相关信息以连接到数据库。现在创建新项目,如果还没有。为了学习,创建一个没有身份验证的Asp.Net5 Web应用程序。现在,转到NuGet包管理器控制台。运行“Install-Package EntityFramework.MicrosoftSqlServer -Pre”。完成后,运行“Install-Package EntityFramework.Commands -Pre”和“Install-Package EntityFramework.MicrosoftSqlServer.Design -Pre”。安装完成后,转到Project.Json文件,在命令部分添加“ef”:“EntityFramework.Commands”。现在,转到命令提示符并cd到您的项目目录。我发现这样做的最简单方法是右键单击您的项目并在文件资源管理器中打开文件夹。一旦你这样做,上升一级,所以你看到的只是一个文件夹。如果您看到项目的所有内容,那么这不是正确的地方。按Shift +右键单击文件夹,您应该看到打开命令窗口的选项。单击该项并在项目目录中打开命令提示符后。运行

  

dnvm使用1.0.0-rc1-update1

或者我发现在某些情况下不能工作。如果这不起作用则运行

  

dnvm使用1.0.0-rc1-final

如果这些都不起作用,则需要安装1.0.0-rc1。一旦其中一个工作,运行

  

dnx ef dbcontext scaffold   “服务器= EnterYourConnectionStringHere;数据库= YourDataBaseNameHere; Trusted_Connection = TRUE;”   EntityFramework.MicrosoftSqlServer --outputDir Models

完成后,您应该拥有从模型目录中的数据库创建的模型。转到模型目录中新创建的Context类。进入后,您将看到覆盖void OnConfiguring方法。删除它。打开你的Startup.cs并将这些使用语句放在顶部。

  

使用YourProject.Models;

     

使用Microsoft.Data.Entity;

现在在Startup.cs中的ConfigureServices方法中添加

  var connection =@"Server=YourConnectionString;Database=YourDatabaseName;Trusted_Connection=True;";

             services.AddEntityFramework()
                 .AddSqlServer()
                .AddDbContext<YourContextName>(options => options.UseSqlServer(connection));

然后剩下的就是为新注册的上下文创建控制器和视图。

  

下面的旧答案

尝试使用fluent API指定关系。像这样:(提示:这是在你的ApplicationDbContext中。)

protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            builder.Entity<DataSensor>()
                .HasMany(p => p.Data)
                .WithOne();
        }
        public DbSet<DataSensor> DataSensor { get; set; }
        public DbSet<GatheredData> GatheredData { get; set; }

你的课程是这样的:

public class DataSensor
    {
        public int Id { get; set; }
        public int DataNodeId { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public bool active;
        public bool alarm;
        public virtual ICollection<DataSensor> Data { get; set; }

    }

    public class GatheredData
    {
        public int Id { get; set; }
        public int DataSensorId { get; set; }
        public DateTime Time { get; set; }
        public float value { get; set; }

        [ForeignKey("DataSensorId")]
        public virtual DataSensor datasensor { get; set; }

    }

你也可以通过这样的惯例来做到这一点

public class DataSensor
    {
        public int Id { get; set; }
        public int DataNodeId { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public bool active;
        public bool alarm;
        public virtual ICollection<DataSensor> Data { get; set; }

    }

    public class GatheredData
    {
        public int Id { get; set; }
        public int DataSensorId { get; set; }
        public DateTime Time { get; set; }
        public float value { get; set; }


        public virtual DataSensor datasensor { get; set; }

    }

或通过此类数据注释

public class DataSensor
    {
        public int Id { get; set; }
        public int DataNodeId { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public bool active;
        public bool alarm;
        public virtual ICollection<DataSensor> Data { get; set; }

    }

    public class GatheredData
    {
        public int Id { get; set; }
        public int DataSensorId { get; set; }
        public DateTime Time { get; set; }
        public float value { get; set; }

        [ForeignKey("DataSensorId")]
        public virtual DataSensor datasensor { get; set; }

    }

如果按惯例执行此操作并且它不起作用,则数据注释可以帮助映射它们。如果所有其他方法都失败了,那么流畅的API将覆盖所有内容并映射关系。

现在,了解如何显示此数据。如果您只是想显示数据而不是编辑它,那么我认为创建局部视图将是您最好的选择。在共享文件夹中创建一个空白视图。将模型添加到新视图中。

@model IEnumerable<DataVisualization.Models.GatheredData>

然后执行foreach循环以迭代该数据。

@foreach (var item in Model)
{
<p>@Html.DisplayFor(modelItem => item.Id)</p>

<p>@Html.DisplayFor(modelItem => item.Time)</p>


<p>@Html.DisplayFor(modelItem => item.Value)</p>


}

然后返回数据传感器的主视图中,将以下内容放在您想要数据的位置。

@Html.Partial("StringNameOfThePartialView", Model.Data)

第一个重载是局部视图的名称,第二个是要传递给该视图的模型数据。