简体   繁体   中英

Extending an Entity Framework property

I have an entity called File, I created a partial class with a property on it.

I was able to use this property in regular constructors and other statements. But this property is not accepted in any linq statement.

I am getting the following exception.

Exception

The specified type member 'FileStatus' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.

Code

var fileEntry = from entry in context.ICFiles
                             where entry.FileName == FileName &&
                                   entry.FileStatus == FileStatus.InProgress
                             select entry;

fileEntry.First().FileStatus = FileStatus.Completed; 
// This is where I get the exception

Property Definition

public partial class ICFile
{
    [DataMemberAttribute()]
    public FileStatus FileStatus
    {
        get
        {
            return (FileStatus)this.Status;
        }
        set
        {
            this.Status = (int)value;
        }
    }
}

I think the problem is that the entity framework is trying to convert your FileStatus property to a column in the database, where it does not exist and there is no mapping information for it to go on as you have defined it in a partial class.

I see that you are trying to cast to an enumeration, because presumably you are using an Entity Framework version before the version 5 beta that apparently has enum support (I may be wrong on that, perhaps it is still missing).

Sadly enumerations do not really work very well in the current Entity Framework version (4.3.1). There are various kludges you can do but none are very satisfactory and you often end up with accidentally loading the entire table into memory or something equally horrendous (see Using ADO.net Entity Framework 4 with Enumerations? How do I do it? ).

Personally I would just not bother with the partial class and do your query like this, to keep things simple:

var fileEntry = from entry in context.ICFiles
                         where entry.FileName == FileName &&
                               entry.Status == (int)FileStatus.InProgress
                         select entry;

fileEntry.First().Status = (int)FileStatus.Completed; 

Not ideal, but it works and it shows what is happening and you know that the where clause will be correctly translated to an equivalent bit of SQL to run against the database (I think that is called "pragmatic").

I don't think the way you use Enums in your code example is causing any issues. The problem is simply that your class extension property is not recognized by EF as a member of ICFiles since it is not really in your edmx model nor a column in your database table. Use the code example user1039947 gave you and you should be fine.

You can however use your original query when doing a LINQ to Object search on an ICFiles IEnumerable instance. This is because LINQ to Entities is translated into SQL before fetching data from the database, while LINQ to objects is done in memory. Your FileStatus property does not exist in your database, only in memory.

Right when I asked the question, I was left with the answer that @user1039947 has posted. However, that's not the one I was expecting as an answer for this question.

I was looking for the ability of Entity framework to utilize the Enum completely. But eventually I figured out that Linq to Entity can't recognize the Enums (it usually recognizes the entities through an attribute starting with Edm, like EdmTypeAttribute, EntityPropertyAttribute etc.)

Linq to Entity of Framework 4.0, has no way to accept the enums as entity object. However, the partial method serves us 80% what we might need from enum.

I have posted a blog with more detail on this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM