4

I have a sqlite database which has some tables and columns like the following:

int Id
text Name
text Comment
...

And my object in my project looks like this:

Public Class Entry {
    public int Id { get; set; }
    public String Name { get; set; }
    public String Comment { get; set; }
    public String Additional { get; set; }
}

This can happen, because my programm need to handle different versions of the database. EF Core now trys to access the Additional field of the database but returns an error that it cannot find the field. (Expected behaviour)

Now my question is, if there is a way to ignore this error and return a default value for the property?

I could bypass the error by making the properties nullable. But i don't want to check each property with .HasValue() before accessing it. Because the real database has 50+ columns in the table.

2 Answers 2

1

https://www.entityframeworktutorial.net/code-first/notmapped-dataannotations-attribute-in-code-first.aspx

Put NotMapped as an attribute on the Additional field:

using System.ComponentModel.DataAnnotations.Schema;

Public Class Entry {
    public int Id { get; set; }
    public String Name { get; set; }
    public String Comment { get; set; }

    [NotMapped]
    public String Additional { get; set; }
}

This tells EF that the field is not a column in the database.

Sign up to request clarification or add additional context in comments.

5 Comments

Depends on the differences in versions between server and client. The Server could send less columns than the client expects.
In your case, is the server the DB and the client your app? or are you referring to a web server and browser client?
The client is for example a windows client that uses a sqlite as a local database. The Server creates and supplies this database to the client. Because the client has to be able to work offline. If the client gets updated but the server is not, the client could expect columns in the database that were not provided by the server. In this case i don't want an exception, but to get default values.
If your database does not contain a field that is on the model, you have to mark the field as not mapped. Anything else would be a hack.
You could look at using the Entity Framework Fluent API to do more complex logic
1

I would advise you to split your domain object from that persisted dto object. That way you can have different dtos with different mappings. Now you can instantiate your domain object with your dto and decide inside your domain object what values are the correct default values.

public class Entry
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Comment { get; set; }
    public string Additional { get; set; }
}

public class EntryDtoV1
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Comment { get; set; }
}

public class EntryDtoV2
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Comment { get; set; }
    public string Additional { get; set; }
}

Now you only need to create some kind of factory that creates the correct repository depending on what database version you query.

4 Comments

The Problem is the following: The client tries to access columns that may not be in the sqlite Database. This can happen if the server is in an older version than the client,
I understand that. You handle this in your factory. Of course your factory has to know with what server version it works. This way you have a clean design.
Okay thank you. This will certainly work for further versions. But for the old ones we have to live with some errors in specific version combinations.
You are welcome :) I had a similar problem and first used another solution. The solution I used was good at the beginning but got worse with time. The second approach used something like the solution I wrote up here and until know it works fine, maybe that will change as well in the future ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.