ආයතන රාමුව 5 වාර්තාවක් යාවත්කාලීන කිරීම


873

ASP.NET MVC3 පරිසරයක් තුළ එන්ටිටි රාමුව 5 තුළ වාර්තාවක් සංස්කරණය කිරීමේ / යාවත්කාලීන කිරීමේ විවිධ ක්‍රම මම ගවේෂණය කර ඇත, නමුත් මේ දක්වා ඒ කිසිවක් මට අවශ්‍ය සියලුම පෙට්ටි ටික් කර නැත. එයට හේතුව මම පැහැදිලි කරන්නම්.

මම ක්‍රම තුනක් සොයාගෙන ඇති අතර එහි වාසි සහ අවාසි සඳහන් කරමි:

ක්රමය 1 - මුල් වාර්තාව පූරණය කරන්න, එක් එක් දේපල යාවත්කාලීන කරන්න

var original = db.Users.Find(updatedUser.UserId);

if (original != null)
{
    original.BusinessEntityId = updatedUser.BusinessEntityId;
    original.Email = updatedUser.Email;
    original.EmployeeId = updatedUser.EmployeeId;
    original.Forename = updatedUser.Forename;
    original.Surname = updatedUser.Surname;
    original.Telephone = updatedUser.Telephone;
    original.Title = updatedUser.Title;
    original.Fax = updatedUser.Fax;
    original.ASPNetUserId = updatedUser.ASPNetUserId;
    db.SaveChanges();
}    

වාසි

  • කුමන ගුණාංග වෙනස් වේදැයි නියම කළ හැකිය
  • දර්ශන සෑම දේපලක්ම අඩංගු විය යුතු නැත

අවාසි

  • මුල් පිටපත පැටවීම සඳහා දත්ත සමුදායේ 2 x විමසුම් පසුව එය යාවත්කාලීන කරන්න

ක්රමය 2 - මුල් වාර්තාව පූරණය කරන්න, වෙනස් කළ අගයන් සකසන්න

var original = db.Users.Find(updatedUser.UserId);

if (original != null)
{
    db.Entry(original).CurrentValues.SetValues(updatedUser);
    db.SaveChanges();
}

වාසි

  • වෙනස් කළ ගුණාංග පමණක් දත්ත සමුදායට යවනු ලැබේ

අවාසි

  • දර්ශන සෑම දේපලක්ම අඩංගු විය යුතුය
  • මුල් පිටපත පැටවීම සඳහා දත්ත සමුදායේ 2 x විමසුම් පසුව එය යාවත්කාලීන කරන්න

ක්රමය 3 - යාවත්කාලීන කරන ලද වාර්තාවක් අමුණා එන්ටිටිස්ටේට් තත්වයට සකසන්න

db.Users.Attach(updatedUser);
db.Entry(updatedUser).State = EntityState.Modified;
db.SaveChanges();

වාසි

  • යාවත්කාලීන කිරීම සඳහා දත්ත සමුදායේ 1 x විමසුම

අවාසි

  • කුමන ගුණාංග වෙනස් වේදැයි සඳහන් කළ නොහැක
  • දර්ශන සෑම දේපලක්ම අඩංගු විය යුතුය

ප්‍රශ්නය

මගේ ප්‍රශ්නය ඔයාලට; මට මෙම අරමුණු සාක්ෂාත් කරගත හැකි පිරිසිදු ක්‍රමයක් තිබේද?

  • කුමන ගුණාංග වෙනස් වේදැයි නියම කළ හැකිය
  • දර්ශන සෑම දේපලක්ම අඩංගු විය යුතු නැත (මුරපදය වැනි!)
  • යාවත්කාලීන කිරීම සඳහා දත්ත සමුදායේ 1 x විමසුම

මෙය පෙන්වා දීමට සුළු කාරණයක් බව මට වැටහී ඇති නමුත් මේ සඳහා සරල විසඳුමක් මට මග හැරී යා හැකිය. ක්‍රමයක් නොවේ නම් එකක් පවතිනු ඇත ;-)


13
ViewModels සහ හොඳ සිතියම්කරණ එන්ජිමක් භාවිතා කරන්න? ඔබගේ දැක්ම ජනනය කිරීම සඳහා ඔබට "යාවත්කාලීන කිරීමට ගුණාංග" පමණක් ලැබේ (පසුව යාවත්කාලීන කිරීමට). යාවත්කාලීන කිරීම සඳහා විමසුම් 2 තවමත් පවතී (මුල් ලබා ගන්න + එය යාවත්කාලීන කරන්න), නමුත් මම මෙය "කොන්" ලෙස නොකියමි. එය ඔබගේ එකම කාර්යසාධන ගැටලුව නම්, ඔබ සන්තෝෂවත් මිනිසෙකි;)
රෆාල් අල්තවුස්

ස්තූතියි @ RaphaëlAlthaus, ඉතා වලංගු කරුණක්. මට මෙය කළ හැකි නමුත් මට වගු ගණනාවක් සඳහා CRUD මෙහෙයුම නිර්මාණය කළ යුතුව ඇත, එබැවින් මා එක් එක් මාදිලිය සඳහා n-1 ViewModel නිර්මාණය කිරීමෙන් මා බේරා ගැනීම සඳහා ආකෘතිය සමඟ කෙලින්ම වැඩ කළ හැකි ක්‍රමයක් සොයමි.
ස්ටොක out ට්

3
හොඳයි, මගේ වර්තමාන ව්‍යාපෘතියේ (බොහෝ ආයතන ද) අපි ආකෘති මත වැඩ කිරීම ආරම්භ කළෙමු, අපට ViewModels සමඟ වැඩ කිරීමේ කාලය අහිමි වේ යැයි සිතමින්. අපි දැන් ViewModels වෙත යන අතර, ආරම්භයේ දී (නොසැලකිලිමත් නොවන) යටිතල පහසුකම් වැඩ කිරීමත් සමඟ, එය දැන් නඩත්තු කිරීම බොහෝ දුරට, වඩා පැහැදිලි හා පහසු ය. වඩාත් සුරක්‍ෂිතයි (අනිෂ්ට "සැඟවුණු ක්ෂේත්‍ර" හෝ ඒ හා සමාන දේවල් ගැන බිය විය යුතු නැත)
රෆාල් අල්තවුස්

1
ඔබේ DropDownLists ජනගහනය කිරීම සඳහා තවත් (භයානක) ViewBags නොමැත (අපගේ CRU (D) දර්ශන සියල්ලම පාහේ අපට අවම වශයෙන් එක් DropDownList එකක්වත් තිබේ ...)
Raphaël Althaus

මම හිතන්නේ ඔබ හරි, ViewModels නොසලකා හැරීමට උත්සාහ කිරීම මගේ නරකයි. ඔව්, ViewBag සමහර විට ටිකක් අපිරිසිදු බවක් පෙනේ. මම සාමාන්‍යයෙන් ඩයිනෝ එස්පොසිටෝගේ බ්ලොග් අඩවියට අනුව තවත් පියවරක් ඉදිරියට ගොස් ඉන්පුට් මොඩල්ස් ද නිර්මාණය කරමි. එක් මාදිලියකට අමතර මාදිලි 2 ක් අදහස් කරයි - doh ;-)
Stokedout

Answers:


680

ඔබ සොයන්නේ:

db.Users.Attach(updatedUser);
var entry = db.Entry(updatedUser);
entry.Property(e => e.Email).IsModified = true;
// other changed properties
db.SaveChanges();

60
හායි ad ලැඩිස්ලාව් ම්ර්න්කා, මට සියලු ගුණාංග එකවර යාවත්කාලීන කිරීමට අවශ්‍ය නම්, මට පහත කේතය භාවිතා කළ හැකිද? db.Departments.Attach (දෙපාර්තමේන්තුව); db.Entry (දෙපාර්තමේන්තුව) .State = EntityState.Modified; db.SaveChanges ();
ෆොයිසුල් කරීම්

23
O ෆොයිසල්: ඔව් ඔබට පුළුවන්.
ලැඩිස්ලාව් ම්ර්න්කා

5
මෙම ප්‍රවේශයේ ඇති එක් ගැටළුවක් නම් ඔබට බරපතල PITA එකක් වන db.Entry () සමච්චල් කළ නොහැකි වීමයි. වෙනත් තැනක හොඳ විහිළු කතාවක් EF සතුව ඇත - (මට කිව හැකි තාක් දුරට) ඔවුන්ට මෙහි එකක් නොමැති වීම තරමක කරදරයකි.
කෙන් ස්මිත්

23
O ෆොයිසල් ඩූයිං සන්දර්භය.එන්ට්‍රි (වස්තුව) .ස්ටේට් = එන්ටිටිස්ටේට්. එය නවීකරණය කරන ලද පරිදි ස්වයංක්‍රීයව අමුණා ඇත ...
හෙලෝ වර්ල්ඩ්

4
@ සැන්ඩ්මන් 4, එයින් අදහස් කරන්නේ අනෙක් සෑම දේපලක්ම එහි තිබිය යුතු අතර එය වර්තමාන වටිනාකමට සැකසිය යුතු බවයි. සමහර යෙදුම් සැලසුම් වලදී, මෙය කළ නොහැකි ය.
ඩෑන් එස්පර්සා

176

පිළිගත් පිළිතුරට මම ඇත්තටම කැමතියි. මේ සඳහා ප්‍රවේශ වීමට තවත් ක්‍රමයක් ඇති බව මම විශ්වාස කරමි. ඔබට දර්ශනයක ඇතුළත් කිරීමට අවශ්‍ය නොවන ඉතා කෙටි දේපල ලැයිස්තුවක් ඔබ සතුව ඇති බව කියමු, එබැවින් ආයතනය යාවත්කාලීන කිරීමේදී ඒවා මඟ හැරෙනු ඇත. එම ක්ෂේත්‍ර දෙක මුරපදය සහ එස්එස්එන් යැයි කියමු.

db.Users.Attach(updatedUser);

var entry = db.Entry(updatedUser);
entry.State = EntityState.Modified;

entry.Property(e => e.Password).IsModified = false;
entry.Property(e => e.SSN).IsModified = false;   

db.SaveChanges();   

මෙම උදාහරණය මඟින් ඔබේ පරිශීලකයින්ගේ වගුවට සහ ඔබගේ දර්ශනයට නව ක්ෂේත්‍රයක් එකතු කිරීමෙන් පසු ඔබේ ව්‍යාපාර තර්කනය තනිවම අත්හැර දැමීමට ඉඩ ලබා දේ.


එස්එස්එන් දේපල සඳහා වටිනාකමක් මා විසින් සඳහන් නොකළ හොත් මට දෝෂයක් ලැබෙනු ඇත, මම ඉස්මෝඩිෆයිඩ් අසත්‍ය ලෙස සකසා තිබුණද එය ආදර්ශ නීතිවලට පටහැනිව දේපල වලංගු කරයි. එබැවින් දේපල NOT NULL ලෙස සලකුණු කර ඇත්නම්, මම ශුන්‍යයට වඩා වෙනස් අගයක් නියම නොකළහොත් එය අසාර්ථක වනු ඇත.
රෝලන්ඩෝසීසී

ඔබට ක්ෂේත්‍රයක් ඔබගේ පෝරමයේ නොමැති නිසා ඔබට දෝෂයක් නොලැබෙනු ඇත. ඔබ නියත වශයෙන්ම යාවත්කාලීන නොකරන ක්ෂේත්‍ර ඔබ අතහැර දමයි, දත්ත සමුදායෙන් එය ඇතුලත් කර ආපසු ලබා දුන් පෝරමය භාවිතා කර එය ලබා ගන්න, සහ එම ක්ෂේත්‍ර වෙනස් නොකරන බව සටහන් කරන්න. ආදර්ශ වලංගුකරණය පාලනය වන්නේ මොඩල්ස්ටේට් තුළ මිස සන්දර්භය තුළ නොවේ. මෙම උදාහරණය දැනට පවතින පරිශීලකයෙකු යොමු කිරීමකි, එබැවින් "යාවත්කාලීන පරිශීලක". ඔබේ SSN අත්‍යවශ්‍ය ක්ෂේත්‍රයක් නම්, එය මුලින්ම නිර්මාණය කරන විට එහි තිබෙන්නට ඇත.
smd

4
මා නිවැරදිව තේරුම් ගන්නේ නම්, "යාවත්කාලීන පරිශීලක" යනු දැනටමත් ෆස්ට් ඕර් ඩීෆෝල්ට් () හෝ ඊට සමාන ජනගහනයක් සහිත වස්තුවක නිදසුනකි, එබැවින් මම වෙනස් කළ ගුණාංග පමණක් යාවත්කාලීන කර අනෙක් අය ISModified = අසත්ය ලෙස සැකසීමි. මෙය හොඳින් ක්‍රියාත්මක වේ. නමුත්, මම උත්සාහ කරන්නේ වස්තුවක් මුලින් ජනගහනය නොකර, කිසිදු ෆස්ට් ඕර් ඩෙෆෝල්ට් () යාවත්කාලීන කිරීමකින් තොරව යාවත්කාලීන කිරීමයි. අවශ්‍ය සියලු ක්ෂේත්‍ර සඳහා මා විසින් වටිනාකමක් නියම නොකළේ නම් මට දෝෂයක් ලැබුණු විට මෙය සිදු වේ, ඔබ පවා එම ගුණාංග මත ISModified = false ලෙස සකසා ඇත. entry.Property (e => e.columnA) .IsModified = අසත්ය; මෙම රේඛාව නොමැතිව ColumnA අසමත් වනු ඇත.
රෝලන්ඩෝසී

ඔබ විස්තර කරන්නේ නව වස්තුවක් නිර්මාණය කිරීමයි. මෙය යාවත්කාලීන කිරීමට පමණක් අදාළ වේ.
smd

1
RolandoCC, දමන්න db.Configuration.ValidateOnSaveEnabled = අසත්ය; db.SaveChanges () ට පෙර;
විල්කි

28
foreach(PropertyInfo propertyInfo in original.GetType().GetProperties()) {
    if (propertyInfo.GetValue(updatedUser, null) == null)
        propertyInfo.SetValue(updatedUser, propertyInfo.GetValue(original, null), null);
}
db.Entry(original).CurrentValues.SetValues(updatedUser);
db.SaveChanges();

මෙය ඇත්තෙන්ම හොඳ විසඳුමක් සේ පෙනේ. ඔබට දේපල අතින් නියම කිරීමට අවශ්‍ය නොවන අතර එය සියලු OPs උණ්ඩ සැලකිල්ලට ගනී - මෙයට වැඩි ඡන්ද ප්‍රමාණයක් නොලැබීමට හේතුවක් තිබේද?
nocarrier

එය එසේ නොවේ. එය විශාලතම "අවාසි" වලින් එකක් වන අතර දත්ත සමුදායට එකකට වඩා පහර දෙයි. ඔබට තවමත් මෙම පිළිතුර සමඟ මුල් පිටපත පැටවීමට සිදුවේ.
smd

1
@smd එය දත්ත ගබඩාවට එක් වරකට වඩා පහර දෙන බව ඔබ කියන්නේ ඇයි? SetValues ​​() භාවිතා කිරීමෙන් මිස එය සිදු වන බව මට නොපෙනේ, නමුත් එය සත්‍යයක් ලෙස නොපෙනේ.
පාර්ලිමේන්තුව

පාර්ලිමේන්තුව මම හිතන්නේ මම ඒක ලියනකොට නිදාගෙන ඉන්න ඇති. සමාව ඉල්ලන්න. සත්‍ය ගැටළුව වන්නේ අපේක්ෂිත ශුන්‍ය අගයක් ඉක්මවා යාමයි. යාවත්කාලීන කළ පරිශීලකයාට කිසියම් දෙයක් ගැන තවදුරටත් සඳහනක් නොමැති නම්, ඔබ එය ඉවත් කිරීමට අදහස් කරන්නේ නම් එය මුල් අගය සමඟ ප්‍රතිස්ථාපනය කිරීම නිවැරදි නොවේ.
smd

22

පලංචිය මඟින් ජනනය කරන ලද යාවත්කාලීන ක්‍රමයට සමාන අතිරේක යාවත්කාලීන ක්‍රමයක් මගේ නිධිය පදනම් පන්තියට එක් කර ඇත. සම්පූර්ණ වස්තුව "වෙනස් කරන ලද" ලෙස සැකසීම වෙනුවට, එය තනි ගුණාංග සමූහයක් සකසයි. (T යනු පන්තියේ සාමාන්‍ය පරාමිතියකි.)

public void Update(T obj, params Expression<Func<T, object>>[] propertiesToUpdate)
{
    Context.Set<T>().Attach(obj);

    foreach (var p in propertiesToUpdate)
    {
        Context.Entry(obj).Property(p).IsModified = true;
    }
}

උදාහරණයක් ලෙස ඇමතීමට:

public void UpdatePasswordAndEmail(long userId, string password, string email)
{
    var user = new User {UserId = userId, Password = password, Email = email};

    Update(user, u => u.Password, u => u.Email);

    Save();
}

මම දත්ත සමුදායට එක් සංචාරයකට කැමතියි. දේපල සමූහයන් පුනරාවර්තනය වීම වළක්වා ගැනීම සඳහා දර්ශන ආකෘති සමඟ මෙය කිරීම වඩා හොඳය. මගේ දර්ශන ආකෘති වලංගු කරන්නන්ගේ වලංගු කිරීමේ පණිවිඩ මගේ ඩොමේන් ව්‍යාපෘතියට ගෙන ඒම වළක්වා ගන්නේ කෙසේදැයි මා නොදන්නා නිසා මම තවමත් එය කර නැත.


ආහා ... දර්ශන ආකෘති සඳහා වෙනම ව්‍යාපෘතියක් සහ දර්ශන ආකෘති සමඟ වැඩ කරන නිධි සඳහා වෙනම ව්‍යාපෘතියක්.
ඉයන් වර්බර්ටන්

11
public interface IRepository
{
    void Update<T>(T obj, params Expression<Func<T, object>>[] propertiesToUpdate) where T : class;
}

public class Repository : DbContext, IRepository
{
    public void Update<T>(T obj, params Expression<Func<T, object>>[] propertiesToUpdate) where T : class
    {
        Set<T>().Attach(obj);
        propertiesToUpdate.ToList().ForEach(p => Entry(obj).Property(p).IsModified = true);
        SaveChanges();
    }
}

ඇයි DbContext.Attach (obj); DbContext.Entry (obj) .State = EntityState.Modified;
nelsontruran

setයාවත්කාලීන ප්‍රකාශයේ කොටස මෙය පාලනය කරයි .
තන්වීර් බදාර්

4

විකල්ප ලැයිස්තුවට එක් කිරීමට පමණි. ඔබට දත්ත ගබඩාවෙන් වස්තුව උදුරා ගත හැකි අතර, ඔබට වෙනස් කිරීමට අවශ්‍ය වාර්තාවේ කොටස් යාවත්කාලීන කිරීමට ඔටෝ මැපර් වැනි ස්වයංක්‍රීය සිතියම්කරණ මෙවලමක් භාවිතා කරන්න ..


3

ඔබගේ භාවිත අවස්ථාව මත පදනම්ව, ඉහත සියලු විසඳුම් අදාළ වේ. කෙසේ වෙතත් මම සාමාන්‍යයෙන් එය කරන්නේ මෙයයි:

සේවාදායක පැති කේතය සඳහා (උදා: කණ්ඩායම් ක්‍රියාවලියක්) මම සාමාන්‍යයෙන් ආයතන පටවා ගතික ප්‍රොක්සි සමඟ වැඩ කරමි. සාමාන්‍යයෙන් කණ්ඩායම් ක්‍රියාවලීන්හිදී, සේවාව ක්‍රියාත්මක වන වේලාවේදී ඔබට දත්ත පැටවිය යුතුය. යම් කාලයක් ඉතිරි කර ගැනීම සඳහා සොයා ගැනීමේ ක්‍රමය භාවිතා කරනවා වෙනුවට දත්ත පැටවීමට මම උත්සාහ කරමි. මම සුභවාදී හෝ අශුභවාදී සමගාමී පාලනයක් භාවිතා කරන ක්‍රියාවලිය මත පදනම්ව (සමාන්තර ක්‍රියාත්මක කිරීමේ අවස්ථා හැරුණු විට මම සෑම විටම සුබවාදීව භාවිතා කරමි, සමහර වාර්තා සරල වර්ග ප්‍රකාශ සමඟ අගුළු දැමිය යුතුය, මෙය දුර්ලභ වුවද). කේතය සහ තත්වය අනුව බලපෑම ශුන්‍යයට ආසන්න වශයෙන් අඩු කළ හැකිය.

සේවාදායකයාගේ පැති අවස්ථා සඳහා, ඔබට විකල්ප කිහිපයක් තිබේ

  1. දර්ශන ආකෘති භාවිතා කරන්න. මාදිලි වලට දේපල යාවත්කාලීනයක් තිබිය යුතුය (නවීකරණය නොකළ-ඇතුළත් කළ-යාවත්කාලීන කළ-මකා දැමූ). පරිශීලක ක්‍රියාවන් මත පදනම්ව මෙම තීරුවට නිවැරදි අගය සැකසීම සේවාදායකයාගේ වගකීම වේ (ඇතුළු කිරීම-යාවත්කාලීන කිරීම-මකා දැමීම). සේවාදායකයාට මුල් අගයන් සඳහා db විමසිය හැකිය, නැතහොත් සේවාදායකයා වෙනස් කළ පේළි සමඟ මුල් අගයන් සේවාදායකයට යැවිය යුතුය. සේවාදායකයා මුල් අගයන් ඇමිණිය යුතු අතර නව අගයන් හැසිරවිය යුතු ආකාරය තීරණය කිරීම සඳහා එක් එක් පේළිය සඳහා යාවත්කාලීන ස්ටේටස් තීරුව භාවිතා කළ යුතුය. මෙම තත්වය තුළ මම සෑම විටම සුභවාදී සමගාමී මුදල් භාවිතා කරමි. මෙය සිදු කරනුයේ ඇතුළත් කිරීම් - යාවත්කාලීන කිරීම - ප්‍රකාශයන් මකා දැමීම මිස තෝරා ගැනීමක් නොවේ, නමුත් ප්‍රස්ථාරය ඇවිදීමට සහ ආයතන යාවත්කාලීන කිරීමට එයට දක්ෂ කේතයක් අවශ්‍ය විය හැකිය (ඔබගේ තත්වය - යෙදුම මත රඳා පවතී). සිතියමකට උදව් කළ හැකි නමුත් CRUD තර්කනය හසුරුවන්නේ නැත

  2. මෙම සංකීර්ණතාවයෙන් වැඩි ප්‍රමාණයක් සඟවන (1 හි විස්තර කර ඇති පරිදි) breeze.js වැනි පුස්තකාලයක් භාවිතා කර එය ඔබේ භාවිතයට ගැලපෙන ලෙස උත්සාහ කරන්න.

එය උපකාරී වේ යැයි සිතමි

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.