EF Map to ValueType throw Exception " Only parameterless constructors and initializers are supported in LINQ to Entities"

Generating SQL and mapping results from EF to struct throws exception . with message

System.NotSupportedException: Only parameterless constructors and initializers are supported in LINQ to Entities.

I have 3 test .

[TestClass]
public class StackOverflowQuestion
{
    private const string userLogin = "alexaShm";
    private const string connectionString = "Data Source=DS;Initial Catalog=db;User ID=usr; Password=XXXXX;Integrated Security=False;Application Name=AppSdbService;";
    private int userId;
    private A_USR usr;

    [TestInitialize]
    public void Init()
    {
        RepoEntryPoint.Initialize(connectionString);
        CleanTestTrash();
    }

    [TestCleanup()]
    public void Cleanup()
    {
        CleanTestTrash();
    }

    private void CleanTestTrash()
    {
        using (SdbEntities context = new SdbEntities(connectionString)) {
            usr = context.A_USR.SingleOrDefault(u => u.USR_LOGIN == userLogin);
            userId = usr.USR_ID;

            //context.Database.Log = Console.Write;
            var VendorsToClear = context.D_G_VENDOR.Where(v => v.VENDOR_NAME.Contains("TestVendor") || v.VENDOR_NAME.Contains("UpdatedName"));

            context.D_G_VENDOR.RemoveRange(VendorsToClear);

            context.SaveChanges();
        }
    }

    struct StructToMap
    {
        public int Id { get; set; }
    }

    class ClassToMap
    {
        public int Id { get; set; }
    }

    [TestMethod]
    public void MapToStruct()
    {
        StructToMap result;
        using (SdbEntities context = new SdbEntities(ConnectionString.Current)) {
            context.Database.Log = (msg) => Console.WriteLine(msg);
            result = context.D_G_VENDOR.Where(v => v.VENDOR_ID == 1).
            Select(vendor =>
            new StructToMap() { Id = vendor.VENDOR_ID }).FirstOrDefault();
        };
        Assert.IsNotNull(result);
        Assert.AreEqual(1, result.Id);
    }

    [TestMethod]
    public void MapToStructViaMethod()
    {
        StructToMap result;
        using (SdbEntities context = new SdbEntities(ConnectionString.Current)) {
            context.Database.Log = (msg) => Console.WriteLine(msg);
            result = context.D_G_VENDOR.Where(v => v.VENDOR_ID == 1).
            Select(Map).FirstOrDefault();
        };
        Assert.IsNotNull(result);
        Assert.AreEqual(1, result.Id);
    }

    private StructToMap Map(D_G_VENDOR vendor) => new StructToMap() { Id = vendor.VENDOR_ID };

    [TestMethod]
    public void MapToClass()
    {
        ClassToMap result;

        using (SdbEntities context = new SdbEntities(ConnectionString.Current)) {
            context.Database.Log = (msg) => Console.WriteLine(msg);
            result = context.D_G_VENDOR.Where(v => v.VENDOR_ID == 1).
            Select(vendor =>
            new ClassToMap() { Id = vendor.VENDOR_ID }).FirstOrDefault();
        };
        Assert.IsNotNull(result);
        Assert.AreEqual(1, result.Id);
    }
}

The result is :

Test Pass Error Message
MapToClass Passed
MapToStruct Failed System.NotSupportedException: Only parameterless constructors and initializers are supported in LINQ to Entities.
MapToStructViaMethod Passed

Printscr test results

the SQL generated by EF code MapToClass is ( output context.Database.Log = (msg) => Console.WriteLine(msg) ):

SELECT
    [Limit1].[C1] AS [C1], 
    [Limit1].[C2] AS [C2]
FROM ( SELECT TOP (1)
           1 AS [C1],
           CAST( [Extent1].[VENDOR_ID] AS int) AS [C2]
       FROM [dbo].[D_G_VENDOR] AS [Extent1]
       WHERE 1 = [Extent1].[VENDOR_ID]
     )  AS [Limit1]

the SQL generated by EF code MapToStructViaMethod is :

SELECT
    [Extent1].[VENDOR_ID] AS [VENDOR_ID],
    [Extent1].[VENDOR_NAME] AS [VENDOR_NAME], 
    [Extent1].[VENDOR_SNAME] AS [VENDOR_SNAME], 
    [Extent1].[IS_ACTIVE] AS [IS_ACTIVE], 
    [Extent1].[CREATED_BY] AS [CREATED_BY], 
    [Extent1].[CREATED_WHEN] AS [CREATED_WHEN], 
    [Extent1].[MODIFIED_BY] AS [MODIFIED_BY], 
    [Extent1].[MODIFIED_WHEN] AS [MODIFIED_WHEN]
FROM [dbo].[D_G_VENDOR] AS [Extent1]
WHERE 1 = [Extent1].[VENDOR_ID]

the SQL code MapToStruct is failed and exception thrown

The Questions are :

Upvotes: 1

Views: 63

Answers (0)

Related Questions