Dapper.Contrib icon indicating copy to clipboard operation
Dapper.Contrib copied to clipboard

Dapper.Contrib ArgumentException: Entity must have at least one [Key] or [ExplicitKey] property

Open troncomputers opened this issue 8 years ago • 10 comments

Hi! I'm getting exception during update

Dapper.Contrib.Extensions.SqlMapperExtensions.Update<T>(IDbConnection connection, T entityToUpdate, IDbTransaction transaction, Nullable<int> commandTimeout)
OptimoKasiarz.Data.Classes.SQL.UpdatePodatnik(string connectionString, Podatnicy pdt) in SQL.cs
con.Update(pdt);
OptimoKasiarz.Pages.Podatnik.EditModel+<OnPostAsync>d__39.MoveNext() in Edit.cshtml.cs
SQL.UpdatePodatnik(SQL.FirmaConnectionString, podatnik);
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Microsoft.AspNetCore.Mvc.RazorPages.Internal.ExecutorFactory+GenericTaskHandlerMethod+<Convert>d__4.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Microsoft.AspNetCore.Mvc.RazorPages.Internal.ExecutorFactory+GenericTaskHandlerMethod+<Execute>d__3.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker+<ExecuteHandlerMethod>d__22.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker+<ExecutePageWithPageModelAsync>d__19.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker+<InvokeInnerFilterAsync>d__15.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeNextResourceFilter>d__22.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeFilterPipelineAsync>d__17.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeAsync>d__15.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Builder.RouterMiddleware+<Invoke>d__4.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware+<Invoke>d__6.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+<Invoke>d__7.MoveNext()

I put [Key] annotation to my class

    public class Podatnicy
    {
        [Key]
        public int PdT_PdTId { get; set; }
        public string PdT_Nazwa { get; set; }
        public string PdT_NIP { get; set; }
        public string PdT_Imie { get; set; }
        public string PdT_Nazwisko { get; set; }
        public string PdT_Miasto { get; set; }
        public string PdT_Ulica { get; set; }
        public string PdT_NrDomu { get; set; }
        public string PdT_NrLokalu { get; set; }
        public string PdT_KodPocztowy { get; set; }
        public string PdT_Wojewodztwo { get; set; }
        public string PdT_NrTel { get; set; }
        public string PdT_Email { get; set; }
        public string PdT_Uwagi { get; set; }
        public bool PdT_Aktywny { get; set; } = true;
        public int? PdT_UrZId { get; set; }
    }

and update function:

        public static void UpdatePodatnik(string connectionString, Podatnicy pdt)
        {
            using (SqlConnection con = new SqlConnection(connectionString))
            {
                con.Open();
                con.Update(pdt);
            }
        }

What am I doing wrong?

troncomputers avatar Aug 17 '17 11:08 troncomputers

Any update on this?

I have kinda the same situation. I've tried with [Key] and [ExplicityKey], and for some reason, after update to 1.50.5 I started seeing: "Entity must have at least one [Key] or [ExplicitKey] property"

erick2red avatar Jun 05 '18 22:06 erick2red

Same problem on 1.50.4 and 1.50.5. Exception: Entity must have at least one [Key] or [ExplicitKey] property I've tried to use Dapper.Contrib.Extensions.Key, Dapper.Contrib.Extensions.ExplicitKey and System.ComponentModel.DataAnnotations.Key

yamaoto avatar Jun 06 '18 16:06 yamaoto

I'm using 1.50.5 and facing the same error. How did you work around this?

dmahely avatar Aug 07 '18 07:08 dmahely

In my case this error was appeared when i set in my update function in repository class, argument with object type Update(object model)

I just changed to generic Update<T>(T model)

yamaoto avatar Oct 02 '18 01:10 yamaoto

In my case this error was appeared when i set in my update function in repository class, argument with object type Update(object model)

I just changed to generic Update<T>(T model)

Originally posted by @yamaoto in https://github.com/StackExchange/Dapper/issues/833#issuecomment-426117208

My problem is very similar to your. I created a function to avoid write open connection every time I use dapper:

    public void EasyUpdate(Object obj)
    {
        using (SqlConnection connection = new SqlConnection(myConnectionString))
        {
            connection.Update(obj);
        }
    }

But Im getting "entity must have at least...." error even especified [Key] I tried, following your post, to change my function to

        public void EasyUpdate<T>(T obj)
        {
            using (SqlConnection connection = new SqlConnection(myConnectionString))
            {
                connection.Update<T>(obj);
            }
        }

But in this case Im getting the error: type t must be a reference type in order to use it as parameter t in type or generic type SqlMapperExtension.Update<T>(IDbConnection,T,IDbTransaction....

What I´m doing wrong? Thanks

DPR77 avatar Mar 19 '20 18:03 DPR77

@DPR77 did you get an answer buddy?

dr-tariq-n-ahmad avatar Apr 07 '20 23:04 dr-tariq-n-ahmad

No, but i finally solved it adding " where T : class":

    public void EasyUpdate<T>(T obj)  where T : class
    {
        using (SqlConnection connection = new SqlConnection(myConnectionString))
        {
            connection.Update<T>(obj);
        }
    }

I hope this helps you too.

DPR77 avatar Apr 08 '20 10:04 DPR77

There is no issue with ver. 2.0.30.

troncomputers avatar Apr 08 '20 10:04 troncomputers

I am using 2.0.30 and had this issue until modified the function as I describe above

DPR77 avatar Apr 08 '20 10:04 DPR77

METHOD

        public static async Task InsertUpdateAttribute(IDbConnection db, DokAtrybuty da)
        {
             if (await HasDocumentAttribute(da.DAt_TrNId, da.DAt_Kod, db))
             {
                 await db.UpdateAsync(da);
             }
             else
             {
                 da.DAt_DeAId = await GetAttributeID(da.DAt_Kod, db);
                 await db.InsertAsync(da);
             }
        }

MODEL

    [Table("CDN.DokAtrybuty")]
    public class DokAtrybuty
    {
        public DokAtrybuty()
        {

        }

        public DokAtrybuty(string code, string value, int id)
        {
            DAt_Kod = code;
            DAt_WartoscTxt = value;
            DAt_TrNId = id;
        }

        [Key]
        public int DAt_DAtId { get; set; }
        public string DAt_Kod { get; set; }
        public int DAt_DeAId { get; set; }
        public int DAt_TrNId { get; set; }
        public int? DAt_CRKId { get; set; }
        public int? DAt_SrZId { get; set; }
        public int? DAt_VaNID { get; set; }
        public int? DAt_DoNID { get; set; }
        public string DAt_WartoscTxt { get; set; }
        public int? DAt_OfdID { get; set; }
        public int? DAt_DokumentTyp { get; set; }
        public int? DAt_DokumentId { get; set; }
        [Write(false)]
        public decimal? DAt_WartoscDecimal { get; set; }
        public byte? DAt_TypJPK { get; set; }
    }

Works for about 2 months. Maybe there is a problem with generics? Is it necessary for you to do generic method for update?

troncomputers avatar Apr 08 '20 10:04 troncomputers