AMcoder - javascript, python, java, html, php, sql

Ինչպես փոխանցել բազային դասը ստացված դասին՝ օգտագործելով Entity Framework-ը

Ես փորձում եմ բազային օբյեկտը փոխանցել ստացված դասի օբյեկտին՝ օգտագործելով Entity Framework:

Ես փորձեցի օգտագործել պատճենի կոնստրուկտորը: Կոնստրուկտորն ինքնին աշխատում է, բայց շրջանակը սխալներ է թույլ տալիս:

Մոդելների դասեր.

public class Member
{
    [Key]
    public string SRU { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public virtual Address Address { get; set; }

}

public class Player : Member
{
    public virtual PlayerPosition Position { get; set; }
    public virtual Doctor Doctor { get; set; }
    public virtual HealthIssue HealthIssue { get; set; }

    public Player()
    {

    }
    public Player(Member m)
    {
        SRU = m.SRU;
        Name = m.Name;
        Email = m.Email;
        Address = m.Address;
    }
}

Իմ փորձը.

DatabaseModel db = new DatabaseModel();

var val = db.Members
            .FirstOrDefault(b => b.Name == "Frank");

val = new Player(val);
db.Members.Update(val);

// Save changes in database
db.SaveChanges();

Ես ակնկալում էի թարմացնել այս նյութը, բայց այն սխալ է թույլ տալիս.

System.InvalidOperationException. «Նվագարկիչ» տեսակի օբյեկտի օրինակը չի կարող հետագծվել, քանի որ {'SRU'}-ի համար նույն բանալի արժեքով մեկ այլ օրինակ արդեն հետագծվում է:

Գոյություն ունեցող սուբյեկտները կցելիս համոզվեք, որ կցված է տվյալ հիմնական արժեքով միայն մեկ միավոր:

Խմբագրել:

Փորձեցի, բայց անունը փոխեցի, բայց տեսակը դեռ նույնն է:

DatabaseModel db = new DatabaseModel();

var val = db.Members
            .FirstOrDefault(b => b.Name == "Yordan");
db.Entry(val).State = EntityState.Detached;

var val2 = new Player(val);
val2.Name = "Frank";

db.Members.Update(val2);
db.SaveChanges();

Sample data

Այսպիսով, ես ստացա Անդամը և Խաղացողը երկարացնում են անդամները: Այդ դեպքում ես ուզում եմ անդամին փոխանցել Player-ին:


  • Նախ, սա կարծես EF Core է, ուստի խնդրում ենք թարմացնել պիտակները: Երկրորդ, դա հնչում է որպես ոչ պատշաճ դիզայն կամ XY խնդիր: val-ը կա՛մ արդեն Player է, և անհասկանալի է, թե ինչ եք փորձում թարմացնել, կամ էլ Member ստացված տեսակ է, որի դեպքում այն ​​չի կարող փոխարկվել Playerի: Խնդրում եմ նկարագրեք, թե իրականում ինչ եք փորձում անել: 10.04.2019
  • Պետք է փոխել (ընդլայնել) Անդամը Player-ի այն, ինչը սովորաբար ծրագրավորման մեջ օգտագործում եք պատճենի կոնստրուկտոր, բայց EF-ն ինձ թույլ չի տալիս դա անել: 10.04.2019
  • Սա նորմալ ծրագրավորում չէ, քանի որ դուք ընտրել եք բոլոր Member ստացված տեսակները պահել մեկ աղյուսակում (TPH տվյալների բազայի ժառանգման ռազմավարություն), որի հիմնական բանալին SRUն է, ուստի այն եզակի է: Սա այն է, ինչ EF-ի սխալ հաղորդագրությունը փորձում է ձեզ ասել: 10.04.2019
  • Լավ, հասկացա. Այս տվյալների բազան առաջին հերթին կատարվել է կոդով: Կա՞ պատկերացում, թե ինչպես վերանախագծել այն: կամ ինչպես փոխել Discriminator 10.04.2019

Պատասխանները:


1

val օբյեկտը, որը փորձում եք թարմացնել, նոր օբյեկտ է, և այն ունի նույն բանալին, ինչ ձեր տվյալների բազայից վերցվածը: Քանի որ բանալին պետք է եզակի լինի, դուք չեք կարող նույն բանալիով հետևել երկու օբյեկտի: Փորձեք նախ անջատել հին առարկան.

DatabaseModel db = new DatabaseModel();
var val = db.Members
        .FirstOrDefault(b => b.Name == "Frank");

var val2 = new Player(val);
db.Entry(val).State = EntityState.Detached;
db.Members.Update(val2);

db.SaveChanges();
10.04.2019
  • Այն դադարում է նետել սխալը, բայց դեռ տեսակը նույնն է, նույնիսկ VS-ը ցույց է տալիս, որ ես անցնում եմ player տեսակը: 10.04.2019

  • 2

    Ես թեմային մոտեցա մյուս կողմից և ստեղծեցի իմ սեփական տվյալների շտեմարանները և օգտագործեցի առկա տվյալների բազայից համատեքստի գեներացումը:

    Diagram

    Արդյունքում ես ստացա համատեքստի նման օրինաչափություն

            public virtual DbSet<Member> Members { get; set; }
            public virtual DbSet<Player> Players { get; set; }
            public virtual DbSet<Senior> Seniors { get; set; }
    

    Եվ երեք գեներացված մոդել

    public partial class Member
        {
            public int Id { get; set; }
            public string Name { get; set; }
    
            public virtual Player Player { get; set; }
        }
    public partial class Player
        {
            public int Id { get; set; }
            public string Position { get; set; }
    
            public virtual Member Member { get; set; }
            public virtual Senior Senior { get; set; }
        }
    public partial class Senior
        {
            public int Id { get; set; }
            public string Kin { get; set; }
    
            public virtual Player Player { get; set; }
        }
    

    Սա այս խնդրի միակ լուծումն է, թե գուցե կան այլընտրանքներ կամ ապացուցված շինություններ։ Ես չգիտեմ, թե արդյոք այս լուծումը լավն է, քանի որ ես դա արել եմ ինտուիտիվ կերպով: Մի կողմից դա իմաստ ունի, քանի որ բոլոր մասերն ունեն ընդհանուր բանալի, և հարաբերությունները 1-1 են, ինչպես ժառանգության մեջ:

    Խմբագրել:

    ամփոփում. Ես գտա, որ EF Core-ից ստացված տեղեկատվությունը չի աջակցում նման լուծմանը, և միակ տարբերակն այն է, որ օգտագործենք պահպանված ընթացակարգը կամ ձեռքով փոխելու տարբերակիչ, եթե մենք օգտագործում ենք մեկ աղյուսակ:

    11.04.2019
    Նոր նյութեր

    Օգտագործելով Fetch Vs Axios.Js-ը՝ HTTP հարցումներ կատարելու համար
    JavaScript-ը կարող է ցանցային հարցումներ ուղարկել սերվեր և բեռնել նոր տեղեկատվություն, երբ դա անհրաժեշտ լինի: Օրինակ, մենք կարող ենք օգտագործել ցանցային հարցումը պատվեր ներկայացնելու,..

    Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար
    Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար Ինչպե՞ս հանգստացնել ձեր միտքը և աշխատեցնել ձեր պրոցեսորը: Ինչպես մնալ հանգիստ և զարգանալ ճնշման տակ...

    Մեքենայի ուսուցում բանկային և ֆինանսների ոլորտում
    Բարդ, խելացի անվտանգության համակարգերը և հաճախորդների սպասարկման պարզեցված ծառայությունները բիզնեսի հաջողության բանալին են: Ֆինանսական հաստատությունները, մասնավորապես, պետք է առաջ մնան կորի..

    Ես AI-ին հարցրի կյանքի իմաստը, այն ինչ ասում էր, ցնցող էր:
    Այն պահից ի վեր, երբ ես իմացա Արհեստական ​​ինտելեկտի մասին, ես հիացած էի այն բանով, թե ինչպես է այն կարողանում հասկանալ մարդկային նորմալ տեքստը, և այն կարող է առաջացնել իր սեփական արձագանքը դրա..

    Ինչպես սովորել կոդավորումը Python-ում վագրի պես:
    Սովորելու համար ծրագրավորման նոր լեզու ընտրելը բարդ է: Անկախ նրանից, թե դուք սկսնակ եք, թե առաջադեմ, դա օգնում է իմանալ, թե ինչ թեմաներ պետք է սովորել: Ծրագրավորման լեզվի հիմունքները, դրա..

    C++-ի օրական բիթ(ե) | Ամենաերկար պալինդրոմային ենթաշարը
    C++ #198-ի ամենօրյա բիթ(ե), Ընդհանուր հարցազրույցի խնդիր. Ամենաերկար պալինդրոմային ենթատող: Այսօր մենք կանդրադառնանք հարցազրույցի ընդհանուր խնդրին. Ամենաերկար palindromic substring...

    Kydavra ICAReducer՝ ձեր տվյալների ծավալայինությունը նվազեցնելու համար
    Ի՞նչ է ICAReducer-ը: ICAReducer-ն աշխատում է հետևյալ կերպ. այն նվազեցնում է նրանց միջև բարձր փոխկապակցված հատկանիշները մինչև մեկ սյունակ: Բավականին նման է PCAreducer-ին, չնայած այն..