Показать страницу профиля компании, используя таблицу ссылок - PullRequest
0 голосов
/ 09 ноября 2018

Я немного новичок на страницах C # и MVC Razor. Я хочу показать страницу профиля компании вошедшему в систему пользователю, который является членом этой компании. У меня есть 3 таблицы для этого представления UsersToAddresses, CustomerNames и Addresses. UsersToAddresses получает идентификатор пользователя, автоматически вставляемый триггером в SQL при регистрации пользователя. Эта таблица имеет только 2 столбца UserId и AddressId. Я сделал это, потому что более одного пользователя может быть членом компании, и я не хотел хранить дубликаты данных. В SQL UsersToAddresses.AddressId связан с Addresses.AddressId внешним ключом. CustomerNames.CustomerId связан с Addresses.CustomerId внешним ключом. Я хочу, чтобы на панели инструментов пользователя отображалось название компании со списком адресов этой компании. У них может быть только один адрес. Я предполагаю, что создание ViewModel является лучшим способом сделать это, у меня есть ViewModel, созданный для страницы. У меня также есть userId как расширение ссылки. Так было бы http: localhost: 3125 / Customers / fdsa531as654few44231431fdvafbfzs [РЕДАКТИРОВАТЬ] После долгих обсуждений с @Marcelo Myara я наконец-то заставил это работать так, как я хочу. Ниже я покажу изменения, помеченные [РЕДАКТИРОВАТЬ]. Код ниже полностью функционален и работает как положено.

Контроллер:

        [Authorize(Roles = "CompanyAdmin")]
    public ActionResult Index(string UserId)
    {
        if (UserId == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
   [EDIT] - "Changed to use modelInstance"
        //Trying to get a view model for customer from the received UserId.
        CompanyOverview modelInstance = CompanyOverview.GetCompanyByUser(UserId, db);
        if (modelInstance == null)
        {
            return HttpNotFound();
        }
        return View(modelInstance);

        // Addresses userAddress = db.Addresses.Find(UserId);
        // if (userAddress == null)
        // {
        //    return HttpNotFound();
        // }
        // return View(userAddress);
    }

В основном это копия Details в контроллере, но для этого используется db.Addresses, и я не использую это в представлении. Я использую ViewModel.

Вот мой взгляд Модель:

    public partial class CompanyOverview
{
    public CompanyOverview()
    [EDIT] - "Not used"
    //{
    //    AddressDetail = new List<Addresses>();
    //}
    [EDIT] - "Not Needed"
    // [Key]

    [Edit] - "Added proper joins for use of referance table"
            //Static method to get an instance of your model when given an userId and DbContext instance.
    public static CompanyOverview GetCompanyByUser(string userId, CustomerEntities db)
    {
        var qCus = from ad in db.Addresses
                   join ua in db.UserToAddresses on ad.AddressId equals ua.AddressId
                   join cus in db.CustomerNames on ad.CustomerId equals cus.CustomerId
                   where (ua.UserId == userId)
                   select new CompanyOverview()
                   {
                       UserId = userId,
                       AddressId = ad.AddressId,
                       Customer = cus.CustomerName,
                       CustomerName = cus,
                       Location = ad.LocationName,
                       Addresses = ad
                   };


        var result = qCus.SingleOrDefault();

        if (result != null)
        {
            result.AddressDetail = db.Addresses.Where(a => a.CustomerId == result.CustomerName.CustomerId);
        };
        return result;
    }

    public string UserId { get; set; }
    public string AddressId { get; set; }
    [EDIT] - "Added for use on page if needed - Customer allows me to show the company name at the top of the razor page"
    public string Customer { get; set; }
    public string Location { get; set; }
    public virtual CustomerNames CustomerName { get; set; }
    public virtual ICollection<Addresses> AddressDetail { get; set; }
}

Это также может быть неверно. Поэтому в результате я должен найти UserId в таблице UsersToAddresses и заставить его извлекать адреса из таблицы адресов, которые соответствуют UserId. Если кто-то может помочь с этим, это будет оценено. Спасибо.

Обновлено 8 ноября 2018 г. - добавлены определения таблиц.

UsersToAddresses:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[UsersToAddresses](
[UserId] [nvarchar](128) NOT NULL,
[AddressId] [int] NOT NULL,
CONSTRAINT [PK_UsersToAddresses] PRIMARY KEY CLUSTERED 
(
[UserId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY= OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON
[PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[UsersToAddresses]  WITH CHECK ADD  CONSTRAINT
[FK_dbo.UsersToAddresses_dbo.AspNetUsers_UserId] FOREIGN KEY([UserId])
REFERENCES [dbo].[AspNetUsers] ([Id])
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[UsersToAddresses] CHECK CONSTRAINT 
[FK_dbo.UsersToAddresses_dbo.AspNetUsers_UserId]
GO

Таблица клиентов:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[CustomerNames](
[CustomerId] [int] IDENTITY(1,1) NOT NULL,
[CustomerName] [nvarchar](max) NOT NULL,
[Status] [int] NOT NULL,
[Terms] [nvarchar](50) NULL,
[TaxCode] [nvarchar](50) NULL,
CONSTRAINT [PK_dbo.CustomerNames] PRIMARY KEY CLUSTERED 
(
[CustomerId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY =OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

ALTER TABLE [dbo].[CustomerNames] ADD  CONSTRAINT
[DF_CustomerNames_Status]
DEFAULT ((1)) FOR [Status]
GO

Таблица адресов:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Addresses](
[AddressId] [int] IDENTITY(1,1) NOT NULL,
[Status] [bit] NULL,
[IsBilling] [bit] NULL,
[IsShipping] [bit] NULL,
[ContactName] [nvarchar](max) NULL,
[Line1] [nvarchar](max) NULL,
[Line2] [nvarchar](max) NULL,
[Country] [nvarchar](100) NULL,
[State] [nvarchar](100) NULL,
[City] [nvarchar](100) NULL,
[ZipCode] [nvarchar](50) NULL,
[EmailAddress] [nvarchar](100) NULL,
[PhoneNumber] [nvarchar](50) NULL,
[FaxNumber] [nvarchar](50) NULL,
[LastUpdated] [datetime] NOT NULL,
[CustomerId] [int] NULL,
 CONSTRAINT [PK_dbo.Addresses] PRIMARY KEY CLUSTERED 
 (
[AddressId] ASC
 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY =
 OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
 GO

ALTER TABLE [dbo].[Addresses] ADD  CONSTRAINT [DF_Addresses_LastUpdated]
DEFAULT (getdate()) FOR [LastUpdated]
GO

ALTER TABLE [dbo].[Addresses]  WITH CHECK ADD  CONSTRAINT
[FK_Addresses_CustomerNames] FOREIGN KEY([CustomerId])
REFERENCES [dbo].[CustomerNames] ([CustomerId])
GO

ALTER TABLE [dbo].[Addresses] CHECK CONSTRAINT
[FK_Addresses_CustomerNames]
GO

Обновление от 10 ноября 2018 г. - добавлен RazorView

RazorView:

@model BestenEquipment.Models.CompanyOverview

@{
ViewBag.Title = "CreateProfile";
Layout = "~/Views/Shared/CustomerDashboardLayout.cshtml";
}


<div id="page-wrapper">
<div class="row">
    <div class="col-lg-12">
        <h2>CompanyOverview</h2>
        <h4>@Html.DisplayFor(model => model.Customer)</h4>
    </div>
    <!-- /.col-lg-12 -->
</div>
<div class="row">
    <div class="col-lg-12">
        Company Addresses:
    [EDIT] - "Added Table for headers"
                    <table class="table">
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Addresses.Status)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Addresses.LocationName)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Addresses.ContactName)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Addresses.EmailAddress)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Addresses.Line1)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Addresses.Line2)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Addresses.IsBilling)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Addresses.IsShipping)
                </th>
            </tr>
    [EDIT] - "Corrected the foreach statement"
          //  @foreach (var item in Model.AddressDetail)
          //  {
          //  <dd> @Html.DisplayFor(model => model.Location)</dd>
          //  }
              @foreach (var item in Model.AddressDetail)
                {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Status)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.LocationName)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.ContactName)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.EmailAddress)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Line1)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Line2)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.IsBilling)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.IsShipping)
                </td>
                <td>
                    @Html.ActionLink("Edit", "UserEdit", "Addresses", new { id = item.AddressId }, null) |
                    @Html.ActionLink("Delete", "Delete", "Addresses", new { id = item.AddressId }, null)
                </td>
            </tr>
            }
            </table>
    </div>
    <!-- /.col-lg-12 -->
</div>
</div>

Так что у вас это есть. Я буду добавлять шифрование в AddressId, чтобы пользователь не мог изменить номер и просматривать записи других клиентов.

1 Ответ

0 голосов
/ 09 ноября 2018

Хорошо, я попытаюсь ответить непосредственно на ваш вопрос (хотя есть много вещей, которые можно изучить и улучшить здесь). Итак:

[Authorize(Roles = "CompanyAdmin")]
public ActionResult Index(string UserId)
{
    if (UserId == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }

    //Trying to get a view model for customer from the received UserId.
    CompanyOverview modelInstance = CompanyOverview.GetCompanyByUser(UserId, db);
    if (modelInstance == null)
    {
        return HttpNotFound();
    } 
    return View(modelInstance);
}

//From your question I'm taking this class as a ViewModel only
public partial class CompanyOverview
{
    //Keeping it here just because you implemented it (if not used elsewhere, just remove this)
    public CompanyOverview()
    {
        AddressDetail = new List<Addresses>();
    }

    //Static method to get an instance of your model when given an userId and DbContext instance. Correct the DbContext type name in the below parameter.
    public static CompanyOverview GetCompanyByUser(int userId, YourDbContext db)
    {
        var qCus = from ad in db.Addresses
                      join ua in db.UsersToAddresses on ad.AddressID equals ua.AddressId
                      join cus in db.CustomerNames on ua.CustomerId equals cus.CustomerId
                      where (ua.UserId == userId)
                      select new CompanyOverview() {
                          UserId = userId,
                          AddressId = ad.AddressId,
                          CustomerName = cus
                      };

        var result = qCus.SingleOrDefault();

        if (result != null) 
        {
            result.AddressDetail = db.Addresses.Where(a => a.CustomerId == result.CustomerName.CustomerId)
        }
        return result;
    }

    //[Key] <- You don't need to define a Key annotation, since this will only be a ViewModel (thus, not having persistence by EF).
    public string UserId { get; set; }
    public string AddressId { get; set; }
    public virtual CustomerNames CustomerName { get; set; }
    public virtual ICollection<Addresses> AddressDetail { get; set; }
}

Проверьте, поможет ли это вам каким-либо образом ... (Я все еще не уверен, правильно ли я вас понял, и, как я уже говорил, есть много вещей, которые можно улучшить здесь - но я пытаюсь ответить на ваш конкретный вопрос. вопрос и использование только вашего типа решения, чтобы я вас не смутил).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...