简体   繁体   中英

MVC C# web service join two tables and combine output

I am working on iTunes/amazon/googlePlay affiliate program and want to add the AffiliateCode to the URL i have in my ExternalLinks Table within the web service. This means that the webservice first collects with the id_cd the different available links from the ExternalLinks[Table] and after is needs to loop over the AffiliateProgram[Table] for each of them to compare if there is a matching affiliate program available.

ExternalLink[Table]
public int id_external_link { get; set; }
public int id_cd { get; set; }
public string Name { get; set; }
public string URL { get; set; }

AffiliateProgram[Table]
public int ID { get; set; }
public string AffiliateName { get; set; }
public string AffiliateSite { get; set; }
public string AffiliateCode { get; set; }
public Nullable<int> CodePosition { get; set; }

The AffiliateProgram[Table]AffiliateName and the ExternalLinks[Table]Name are always the same.

This is how i was setting it up but i don't get it to work yet and got stuck now for the last days.

[Route("api/Cds/ExternalLinks/{id_cd}")]
    public async Task<List<ExternalLink>> GetAllExternalLinks(int id_cd)
    {
        List<ExternalLink> externallinks = await db.ExternalLink
            .Where(EL => EL.id_cd == id_cd)
            .ToListAsync();

        List<ExternalLink> ListAllExternalLinks = new List<ExternalLink>();
        for (int i = 0; i < 4; i++)
        {
           ExternalLink CDEL = new ExternalLink();

           if (CDEL.Name == "Itunes") {   

           var query = from EL in db.ExternalLink
                       join AP in db.AffiliateProgram on EL.Name equals AP.AffiliateName
                       select new
                       {
                        AffiliateName = AP.AffiliateName,
                        Name = EL.Name,
                        AffilateCode = AP.AffiliateCode,
                        URL = EL.URL
                       };

            URL = query.First().Name + "?mt=1&at=" + query.First().AffiliateCode + "&ct=" + id_cd;  

            }

            ListAllExternalLinks.Add(CDEL);

        }   
        ListAllExternalLinks.AddRange(externallinks);
        return ListAllExternalLinks;
    }

this results in the following in postmaster, with 4 empty results:

[
{},
{},
{},
{},
{
"id_external_link": 1459,
"id_cd": 13376,
"name": "Itunes",
"url": "https://itunes.apple.com/...countingcrows"
},
{
"id_external_link": 1460,
"id_cd": 13376,
"name": "Amazon",
"url": "https://www.amazon.com/....countingcrows"
},
{
"id_external_link": 1461,
"id_cd": 13376,
"name": "GooglePlay",
"url": "https://play.google.com/...countingcrows"
}
]

Your query is returning an anonymous object and you are accessing attributes not being returned by the query. You could change your query to return the following attributes and then access them:

        var query = from EL in db.ExternalLink
                    join AP in db.AffiliateProgram on EL.Name equals AP.AffiliateName
                    select new
                    {
                        AffiliateName = AP.AffiliateName
                        Name = EL.Name
                        AffiliateCode = AP.AffiliateCode
                    };

You have a number of syntax errors that would prevent this code from even compiling, so it's a little difficult to figure out exactly where you're going wrong, in general. At least make sure your code compiles first, and then if you're still not getting the results you need, we can help you.

That said, it looks like you're making this much more difficult than it needs to be. If you want to be able to join the two tables, you should create a foreign key between them. If a particular link belongs to a particular affiliate program, then actually create that relationship:

public class ExternalLink
{
    ...

    [ForeignKey("AffiliateProgram")]
    public int AffiliateProgramId { get; set; }
    public virtual AffiliateProgram AffiliateProgram { get; set; }
}

Then, you can simply include the affiliate program when you query and call it a day:

var externalLinks = db.ExternalLinks
    .Include(m => m.AffiliateProgram)
    .Where(m => m.id_cd == id_cd)
    .ToListAsync();

Then, as you're iterating over the links:

var affiliateCode = link.AffiliateProgram.AffiliateCode;

Super simple.

Well got it to work (had to change lots of stuff actually), thank you S.Dav for the explication how to connect the other database table and modify the string with the data. Very useful lesson.

    [Route("api/CDS/ExternalLink/{id_cd}")]
    public async Task<List<ExternalLink>> GetAllExternalLinks(int id_cd)
    {

        List<ExternalLink> ListAllExternalLinks = new List<ExternalLink>();

            foreach (var item in await db.ExternalLink
                .Where(EL => EL.id_cd == id_cd)
                .ToListAsync())
            {

            ExternalLink CDEL = new ExternalLink();

            CDEL.id_cd = item.id_cd;
            CDEL.Name = item.Name;

            if (CDEL.Name == "Itunes") {

                var query = from EL in db.ExternalLink
                        join AP in db.AffiliateProgram on EL.Name equals AP.AffiliateName
                        select new
                        {
                        AffiliateName = AP.AffiliateName,
                        Name = EL.Name,
                        AffilateCode = AP.AffiliateCode,
                        URL = EL.URL
                        };

                CDEL.URL = item.URL + query.First().Name + "?mt=1&at=" + query.First().AffilateCode + "&ct=" + id_cd;          
            }
            ListAllExternalLinks.Add(/CDEL);
        }
        return ListAllExternalLinks;
    }

Results in a perfect web-service with the affiliate code connected to the iTunes in this case :-) Would love to have a solution tho that could actually find the affiliate code itself but this works for now :-)

[
 {
"id_cd": 13376,
"name": "Itunes",
"url": "https://itunes.apple.com/...../countingcrows?mt=1&at=1010lmNu&ct=13376"
 },
 {
"id_cd": 13376,
"name": "Amazon"
"url": "https://www.amazon.com...../countingcrows"
 },
 {
"id_cd": 13376,
"name": "GooglePlay"
 "url": "https://play.google.com/....countingcrows?id=AEIKS4IbfNk&hl=en"
 }
]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM