Как сгенерировать уникальный номер при сохранении данных в MVC с использованием Entity Framework согласно ключу max Identity таблицы? - PullRequest
3 голосов
/ 01 февраля 2020

Мне нужно закоротить следующий код.

Мне нужно сгенерировать и сохранить уникальный ссылочный номер в столбце как R00001, R00002, R00003, et c. Здесь 1, 2 и 3 основаны на значениях идентификационных ключей.

Для этого я дважды написал db.SaveChanges(). Сначала я сохраняю данные, выбираю эти сохраненные данные и обновляю их, генерируя этот уникальный ключ. Можно ли сгенерировать этот ключ и передать при сохранении сразу?

Итак, мне не нужно выбирать данные после сохранения и обновлять их, снова вызывая db.SaveChanges() дважды. Вот мой MVC код контроллера (MVC action).

[HttpPost]
public ActionResult Create(RateTable model, HttpPostedFileBase[] files)
{
  RateTable objRC = null;
  if (model.RatecontractId >= 1)
  {
      objRC = db.RateTables.FirstOrDefault(rc => rc.RatecontractId == model.RatecontractId);
  }

  if (objRC == null && model.RatecontractId <= 0)
  {
      objRC = new RateTable();

      objRC.CountryCode = model.CountryCode;
      objRC.CompanyCode = model.CompanyCode;
      objRC.CustomerName = model.CustomerName;
      objRC.Remarks = model.Remarks;
      objRC.CreatedDate = DateTime.Now;
      objRC.CreatedBy = User.Identity.Name;

      //Saving data into the database table.
      db.RateTables.Add(objRC);
      db.SaveChanges();

      string uniqueRefNo = "R" + string.Format("{0:D5}", objRC.RatecontractId); 
      int rateContractId = objRC.RatecontractId;

      //For updating the unique reference number of the contract.
      RateTable result = (from rc in db.RateTables where rc.RatecontractId == rateContractId select rc).SingleOrDefault();
       if (result != null)
       {
          result.UniqueRefNo = uniqueRefNo;
          db.SaveChanges();
       }
   }
}

Я сохраняю данные в столбце UniqueRefNo, как показано ниже:

RatecontractId  CountryCd   CompanyCd   UniqueRefNo
---------------------------------------------------
1               C0U001      C0M001      R00001
2               C0U001      C0M001      R00002
3               C0U001      C0M001      R00003
4               C0U001      C0M001      R00004
5               C0U001      C0M001      R00005

Я хочу уменьшить этот код, потому что я также сохраняю файлы, которые нужно было сохранить в формате, подобном R00001.pdf, R00002.pdf, R00003.pdf, et c.

Вот код сохранения файла с переименованным файлом имя согласно уникальному номеру ссылки.

if (files != null)
{
  foreach (HttpPostedFileBase file in files)
  {
    if (file != null)
    {
      //To generate the file name of the rate contract.
      var fileName = "RC" + string.Format("{0:D5}", objRC.RatecontractId);
      var extension = Path.GetExtension(file.FileName);
      fileName = fileName + extension;

      string path = string.Format("~/Documents/PDF/{0}", fileName);

       if (System.IO.File.Exists(Server.MapPath(path)))
          System.IO.File.Delete(Server.MapPath(path));
       file.SaveAs(Server.MapPath(path));

       RateTable resultForfiles = (from rc in dbTender.RateTables where 
       rc.RatecontractId == objRC.RatecontractId select rc).SingleOrDefault();
       if (resultForfiles != null && (extension.ToLower() == "pdf" || extension.ToLower() == ".pdf"))
       {
          resultForfiles.PdfFilePath = fileName;
       }
       if (resultForfiles != null && extension.ToLower() != "pdf" && extension.ToLower() != ".pdf")
       {
          resultForfiles.WordExcelFilePath = fileName;
       }
       dbTender.SaveChanges(); //Third thime calling `SaveChanges()`
     }
   }
}

Ответы [ 3 ]

4 голосов
/ 03 февраля 2020

В качестве опции можно создать столбец идентификаторов и вычисляемый столбец, в вычисляемом столбце рассчитать требуемое значение на основе столбца идентификаторов. Например:

CREATE TABLE [dbo].[Table1](
    [Id] INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [Name] NVARCHAR(50) NOT NULL,
    [Code]  AS (('R'+ REPLICATE('0',(5) - LEN(CONVERT([NVARCHAR](50),[Id])))) +
        CONVERT([NVARCHAR](50),[Id]))
)

Затем, когда вы вставляете в таблицу, используя EF или запрос, подобный этому:

INSERT INTO [dbo].[Table1]([Name]) VALUES (N'Something')

Результат:

| Id   | Name           | Code              |
=============================================
| 1    | Something      | R00001            |

Важное примечание

Прежде чем выбирать какое-либо решение, независимо от того, вычисляется ли столбец, последовательность или триггер, убедитесь, что вам необходимо сохранить такой вычисленный код в базе данных. Я сомневаюсь. Я думаю, вам не нужно генерировать и хранить ссылочный код на стороне базы данных , достаточно использовать ключ объекта в качестве ссылочного номера / внешнего ключа везде, где требуется логическое или физическое отношение.

  • Использование столбца идентификации: * Вы можете определить столбец идентификации Id. Затем, после вставки yourEnitty в дБ, после SaveChanges(), yourEntity.Id будет содержать новое вставленное значение идентификатора, и вам не потребуется дополнительный вызов для дБ. Затем вы можете использовать тот же идентификатор в качестве ссылки (например, имя файла).

  • Использование столбца Guid: * Вы можете определить столбец Guid Id. Затем перед тем, как вставить yourEnitty в db, присвойте Guid.NewId() столбцу Id, а затем вы можете использовать тот же guid в качестве ссылки (например, как имя файла).

Рассмотрим следующие пункты:

  • Имя или ключ файла в вашем хранилище и ключ объекта в вашей базе данных - это ваша территория, и конечный пользователь не имеет к этому никакого отношения.
  • Возможно, вы захотите использовать хранилище, например Azure Blob, SQL База данных, Файловая система и т. Д., И в любой из этих технологий хранения вы можете использовать другой ключ / имя для файла.
  • Единственное, что может сказать конечное использование: «Я хотел бы видеть ссылку на файлы с понятным именем» или «Я хотел бы иметь понятное имя при загрузке файла», и это действительно Вы легко можете указать такое дружественное имя в сетке или при загрузке.

Мой совет - сохранять и извлекать файл, используя ключ, например, ключ guid. Затем в вашем действии загрузки вы можете легко отправить файл с другим именем для загрузки, например:

public ActionResult Download(Guid id)
{
    var file = Server.MapPath($"~/Content/uploads/{id}.pdf";
    return File(file, "application/pdf", "something.pdf");
}
1 голос
/ 03 февраля 2020

Кажется, что проблема второго вызова базы данных решается с помощью триггеров базы данных после вставки.

Все остальные параметры кода не решат проблему второго вызова, например использование хранимых процедур или выполнение SQL запросы.

Я предлагаю разделить работу на уровень базы данных, выполненный с помощью триггеров и кода C#, для решения проблемы сохранения файла.

После триггера вставки: https://www.tech-recipes.com/rx/41414/sql-server-coding-the-after-insert-trigger-in-sql-server/

0 голосов
/ 03 февраля 2020

Если вы используете Microsoft SQL Server, тогда это идеальная работа для ПОСЛЕДОВАТЕЛЬНОСТЕЙ.

ПОСЛЕДОВАТЕЛЬНОСТИ существуют уже в настоящее время в мире Microsoft.

Они предназначены для производства последовательные значения, которые могут быть глобальными для всей базы данных.

Очень легко создать и очень легко использовать.

Пожалуйста, ознакомьтесь с документацией: ПОСЛЕДОВАТЕЛЬНОСТИ В SQL SERVER

Затем можно использовать выходные данные последовательности, чтобы «составить» строку, или даже просто использовать значение для установки столбца первичного ключа или уникального ключа в операторе вставки.

SEQUENCES - это идеальная альтернатива столбцам «Identity».

И они соответствуют стандарту ANSI / ISO для SQL.

Здесь приведена ссылка с некоторой информацией и даже примерами того, как используйте SEQUENCES:

ПРИМЕРЫ И ДРУГУЮ ИНФОРМАЦИЮ

SEQUENCES также можно использовать как ограничения значений по умолчанию в столбцах во время операторов вставки.

W ARNING: Насколько я знаю, эта функция была доступна в SQL Server 2012 и новее ....

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