Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EF 2.1 Value Conversion fails with custom type #11199

Closed
JohnyL opened this issue Mar 8, 2018 · 4 comments
Closed

EF 2.1 Value Conversion fails with custom type #11199

JohnyL opened this issue Mar 8, 2018 · 4 comments
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug
Milestone

Comments

@JohnyL
Copy link

JohnyL commented Mar 8, 2018

I have custom type TimesRecords (which converts XML from database into objects) and entity which uses it:

public class TimesHistory
{
    [Key]
    public int DetailId { get; set; }
    public TimesRecords Records { get; set; }
}

Here's converter:

public class TimesHistoryConfiguration : IEntityTypeConfiguration<TimesHistory>
{
    public void Configure(EntityTypeBuilder<TimesHistory> builder)
    {
        builder
            .Property(p => p.Records)
            .HasConversion(
                tr => tr.ToString(),
                tr => new TimesRecords(tr));
    }
}

For full picture, here's T-SQL of table:

CREATE TABLE dbo.TimesHistory
(
	DetailId int not null,
	Records xml not null
);

So, when I run this simple code:

var history = context.TimesHistory.Where(th => th.DetailId == 1).First();
var times = history.Records;
MessageBox.Show($"Count: {times.Count()}");

I get the following error:

System.InvalidOperationException:
'The property 'Records' cannot be added to the entity type 'TimesHistory' because a navigation property with the same name already exists on entity type 'TimesHistory'.'

Further technical details

EF Core version: 2.1.0-preview1-final
Database Provider: Microsoft.EntityFrameworkCore.SqlServer
Operating system: Windows 10 x64 Home 1709 Build 16299.125
IDE: Visual Studio 2017 15.6.0 Preview 7.0

@ajcvickers
Copy link
Member

@JohnyL Can you post the code for the TimesRecords class?

@JohnyL
Copy link
Author

JohnyL commented Mar 9, 2018

@ajcvickers Here are TimesRecords and related TimeRecord classes.

TimesRecords class

public class TimesRecords : IEnumerable<TimeRecord>
{
    private List<TimeRecord> timeRecords = null;

    public TimesRecords(string xml)
    {
        timeRecords = new List<TimeRecord>();
        if (xml != null)
        {
            foreach (var entry in XElement.Parse(xml).Elements())
            {
                timeRecords.Add(new TimeRecord(entry));
            }
        }
    }

    public IEnumerator<TimeRecord> GetEnumerator()
    {
        foreach (var timeRecord in timeRecords)
            yield return timeRecord;
    }

    public void Add(DateTime recordTime, int hours, int minutes)
    {
        int nextId = timeRecords.Count == 0 ? 1 : timeRecords.Max(r => r.Id) + 1;
        timeRecords.Add(new TimeRecord(nextId, recordTime, hours, minutes));
    }

    public override string ToString()
    {
        var xml = new XElement("records",
            from rec in timeRecords
            select new XElement("record",
                new XAttribute("id", rec.Id),
                new XAttribute("time", rec.RecordTime),
                new XAttribute("hours", rec.Hours),
                new XAttribute("minutes", rec.Minutes)));
        return xml.ToString();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

TimeRecord class

public class TimeRecord
{

    internal TimeRecord(int id, DateTime recordTime, int hours, int minutes)
    {
        Id = id;
        RecordTime = recordTime;
        Hours = hours;
        Minutes = minutes;
    }

    internal TimeRecord(XElement xml)
    {
        Id = int.Parse(xml.Attribute("id").Value);
        RecordTime = DateTime.Parse(xml.Attribute("time").Value);
        Hours = int.Parse(xml.Attribute("hours").Value);
        Minutes = int.Parse(xml.Attribute("minutes").Value);
    }
    public int Id { get; set; }
    public DateTime RecordTime { get; set; }
    public int Hours { get; set; }
    public int Minutes { get; set; }
}

@ajcvickers
Copy link
Member

Looks like it could be the same root cause as #11074. @AndriySvyryd? @smitpatel?

@AndriySvyryd
Copy link
Member

Sounds more like another case of #10765

@ajcvickers ajcvickers added this to the 2.1.0 milestone Mar 9, 2018
AndriySvyryd added a commit that referenced this issue Mar 20, 2018
@AndriySvyryd AndriySvyryd removed their assignment Mar 21, 2018
@AndriySvyryd AndriySvyryd added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Mar 21, 2018
@ajcvickers ajcvickers modified the milestones: 2.1.0-preview2, 2.1.0 Nov 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug
Projects
None yet
Development

No branches or pull requests

3 participants