J'ai obtenu mon code fonctionne très bien, mais je ne suis pas vraiment sûr si l'approche que j'ai prise est une meilleure pratique ou non. Donc, j'ai décidé de demander dans ce forum à la place.Insérer ou mettre à jour les données du modèle mappé dans la base de données
Voici donc ma situation:
Je suis mon modèle qui ressemble à ceci:
public class Member
{
[Range(1, int.MaxValue)]
public int? MemberID { get; set; }
[Required]
public List<MemberExperience> MemberExperiences { get; set; }
[Required]
public string MemberAddress { get; set; }
[Required]
public MemberInformation MemberInformation { get; set; }
}
public class MemberExperience
{
[Required]
[Range(1, int.MaxValue)]
public int FromYear { get; set; }
[Required]
[Range(1, int.MaxValue)]
public int ToYear { get; set; }
[Required]
public string CompanyAddress { get; set; }
[Required]
public string ProgrammingLanguage { get; set; }
}
public class MemberInformation
{
[Required]
public string FullName { get; set; }
[Required]
public DateTime BirthDate { get; set; }
[Required]
public string TelephoneNumber { get; set; }
}
Et du côté client, ce que je passe au serveur est comme ceci:
{
"MemberExperiences": [
{
"FromYear": 2005,
"ToYear": 2008,
"CompanyAddress": "string",
"ProgrammingLanguage": "Javascript"
},
{
"FromYear": 2009,
"ToYear": 2012,
"CompanyAddress": "string",
"ProgrammingLanguage": "C++"
},
{
"FromYear": 2013,
"ToYear": 2017,
"CompanyAddress": "string",
"ProgrammingLanguage": "C#"
}
],
"MemberAddress": "string",
"MemberInformation": {
"FullName": "string",
"BirthDate": "1992-01-01",
"TelephoneNumber": "string"
}
}
Puis mon contrôleur ressemblait à ceci (les données que je veux passer du côté client, seront converties en Member
modèle qui ont toutes les données dedans):
[HttpPost]
public HttpActionResult AddMember([FromBody] Member member)
{
var response = AddMemberToDatabase(member);
return Ok(response);
}
Mais, puisque je ne savais pas comment Dapper
(j'utilise Dapper
pour la communication à la base de données) convertir la variable cartographiée (dans ce cas MemberExperience
et MemberInformation
) en objet unique et d'être reconnu. Donc, ce que je faisais est comme ceci:
Prenez toutes les données membres, mais avant l'insérer dans la base de données, je vais faire une classe stockée la liste des données de
MemberExperience
etMemberInformation
.Joignez toutes les données dans une seule longue chaîne avec un séparateur séparé que seule la base de données permet d'y accéder et le connaît.
SingleMember Classe:
public class SingleMember
{
public int? MemberID { get; set; }
public string FromYears { get; set; }
public string ToYears { get; set; }
public string CompanyAddresses { get; set; }
public string ProgrammingLanguages { get; set; }
public string MemberAddress { get; set; }
public string FullName { get; set; }
public DateTime BirthDate { get; set; }
public string TelephoneNumber { get; set; }
}
fonction AddMemberToDatabase:
private int AddMemberToDatabase(Member members)
{
var separator = "$Format";
var singleMember = new SingleMember
{
FromYears = string.Join(separator, members.MemberExperiences.Select(x => x.FromYear)),
ToYears = string.Join(separator, members.MemberExperiences.Select(x => x.ToYear)),
CompanyAddresses = string.Join(separator, members.MemberExperiences.Select(x => x.CompanyAddress)),
ProgrammingLanguages = string.Join(separator, members.MemberExperiences.Select(x => x.ProgrammingLanguage)),
MemberAddress = members.MemberAddress;
FullName = members.MemberInformation.FullName;
BirthDate = members.MemberInformation.BirthDate;
TelephoneNumber = members.MemberInformation.TelephoneNumber;
};
using (TransactionScope trans = new TransactionScope())
using (IDbConnection conn = new SqlConnection("MyConnection"))
{
conn.Open();
int rowsAffected = conn.Execute("MyStoredProcedure", singleMember);
trans.Complete();
return rowsAffected;
}
}
Puis, à partir du MyStoredProcedure
, il partagera les données jointes par le format défini $Format
et insérez-le dans le tableau 1 par 1 jusqu'à ce que l'élément qui est en train d'être divisé n o plus à gauche d'être divisé.
ALTER PROCEDURE [dbo].[MyStoredProcedure]
(
@FromYears NVARCHAR(MAX), // will be 2005$Format2009$Format2013
@ToYears NVARCHAR(MAX), // will be 2008$Format2012$Format2017
@CompanyAddresses NVARCHAR(MAX), // will be string$Formatstring$Formatstring
@ProgrammingLanguages NVARCHAR(MAX), // will be Javascript$FormatC++$FormatC#
@MemberAddress NVARCHAR(MAX),
@FullName NVARCHAR(MAX),
@BirthDate DATETIME,
@TelephoneNumber NVARCHAR(MAX)
)
AS
BEGIN
DECLARE
@MemberCount INT,
@FromYear INT,
@ToYear INT,
@CompanyAddress NVARCHAR(MAX),
@ProgrammingLanguage NVARCHAR(MAX)
DECLARE @FromYearTable TABLE (
[ID] INT IDENTITY,
[FromYear] INT NOT NULL
)
DECLARE @ToYearTable TABLE (
[ID] INT IDENTITY,
[ToYear] INT NOT NULL
)
DECLARE @CompanyAddressTable TABLE (
[ID] INT IDENTITY,
[CompanyAddress] NVARCHAR(MAX) NOT NULL
)
DECLARE @ProgrammingLanguageTable TABLE (
[ID] INT IDENTITY,
[ProgrammingLanguage] NVARCHAR(MAX) NOT NULL
)
DECLARE @MemberTable TABLE (
[ID] INT IDENTITY,
[FromYear] INT NOT NULL,
[ToYear] INT NOT NULL,
[CompanyAddress] NVARCHAR(MAX) NOT NULL,
[ProgrammingLanguage] NVARCHAR(MAX) NOT NULL
)
INSERT INTO @FromYearTable
SELECT [SplittedItem] FROM [StringSplit] (@FromYears, '$Format')
INSERT INTO @ToYearTable
SELECT [SplittedItem] FROM [StringSplit] (@ToYears, '$Format')
INSERT INTO @CompanyAddressTable
SELECT [SplittedItem] FROM [StringSplit] (@CompanyAddresses, '$Format')
INSERT INTO @ProgrammingLanguageTable
SELECT [SplittedItem] FROM [StringSplit] (@ProgrammingLanguages, '$Format')
INSERT INTO @MemberTable
SELECT a.[FromYear], b.[ToYear], c.[CompanyAddress], d.[ProgrammingLanguage]
FROM @FromYearTable a
INNER JOIN @ToYearTable b ON a.[ID] = b.[ID]
INNER JOIN @CompanyAddressTable c ON a.[ID] = c.[ID]
INNER JOIN @ProgrammingLanguageTable d ON a.[ID] = d.[ID]
/*
Will be like:
ID FromYear ToYear CompanyAddress ProgrammingLanguage
1 2005 2008 string Javascript
2 2009 2012 string C++
3 2013 2017 string C#
*/
SET @MemberCount = (SELECT COUNT(*) FROM @MemberTable)
WHILE (@MemberCount > 0)
BEGIN
SET @FromYear = (SELECT TOP 1 [FromYear] FROM @MemberTable WHERE [ID] = @MemberCount)
SET @ToYear = (SELECT TOP 1 [ToYear] FROM @MemberTable WHERE [ID] = @MemberCount)
SET @CompanyAddress = (SELECT TOP 1 [CompanyAddress] FROM @MemberTable WHERE [ID] = @MemberCount)
SET @ProgrammingLanguage = (SELECT TOP 1 [ProgrammingLanguage] FROM @MemberTable WHERE [ID] = @MemberCount)
INSERT INTO [MyTable] (@FromYear, @ToYear, @CompanyAddress, @ProgrammingLanguage, @MemberAddress, @FullName, @BirthDate, @TelephoneNumber)
SET @MemberCount -= 1
END
END
Y a-t-il une meilleure façon de procéder?
Votre réponse a été très appréciée.
Merci
Comment les données sont-elles mappées dans la base de données? Combien de tables stockez-vous des données? Pouvez-vous fournir quelques détails à ce sujet aussi? –
Salut @PiyushKhanna, s'il vous plaît voir la question mise à jour ci-dessus, j'ai inclus la procédure stockée ainsi. Merci – Reinhardt