Entity Framework 6 Code First function mapping

后端 未结 4 763
青春惊慌失措
青春惊慌失措 2020-12-05 13:18

I want integrate Entity Framework 6 to our system, but have problem.

  1. I want to use Code First. I don’t want to use Database First *.edmx file for other reasons
相关标签:
4条回答
  • 2020-12-05 14:09

    now Entity Framework is not beta, so maybe you solved your problem, but this one solved my problem How to use scalar-valued function with linq to entity?

    0 讨论(0)
  • 2020-12-05 14:10

    Haven't tried this yet, but Entity Framework 6.1 includes public mapping API. Moozzyk has implemented Store Functions for EntityFramework CodeFirst using this new functionality.

    Here's what the code looks like:

    public class MyContext : DbContext
    {
        public DbSet<Customer> Customers { get; set; }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Add(new FunctionsConvention<MyContext>("dbo"));
        }
    
        [DbFunction("MyContext", "CustomersByZipCode")]
        public IQueryable<Customer> CustomersByZipCode(string zipCode)
        {
            var zipCodeParameter = zipCode != null ?
                new ObjectParameter("ZipCode", zipCode) :
                new ObjectParameter("ZipCode", typeof(string));
    
            return ((IObjectContextAdapter)this).ObjectContext
                .CreateQuery<Customer>(
                    string.Format("[{0}].{1}", GetType().Name, 
                        "[CustomersByZipCode](@ZipCode)"), zipCodeParameter);
        }
    
        public ObjectResult<Customer> GetCustomersByName(string name)
        {
            var nameParameter = name != null ?
                new ObjectParameter("Name", name) :
                new ObjectParameter("Name", typeof(string));
    
            return ((IObjectContextAdapter)this).ObjectContext.
                ExecuteFunction("GetCustomersByName", nameParameter);
        }
    }
    
    0 讨论(0)
  • 2020-12-05 14:18

    You can get the Store type from the primitive type with a helper method:

        public static EdmType GetStorePrimitiveType(DbModel model, PrimitiveTypeKind typeKind)
        {
            return model.ProviderManifest.GetStoreType(TypeUsage.CreateDefaultTypeUsage(
                PrimitiveType.GetEdmPrimitiveType(typeKind))).EdmType;
        }
    

    In your example, you'd have to change the return parameter's type:

    var edmType = GetStorePrimitiveType(model, PrimitiveTypeKind.String);
    


    I found the help I needed here: http://entityframework.codeplex.com/discussions/466706

    0 讨论(0)
  • 2020-12-05 14:18

    Here are all the steps needed [Tested] :

    Install-Package EntityFramework.CodeFirstStoreFunctions
    

    Declare a class for output result:

    public class MyCustomObject
    {
       [Key]
       public int Id { get; set; }
       public int Rank { get; set; }
    }
    

    Create a method in your DbContext class

    [DbFunction("MyContextType", "SearchSomething")]
    public virtual IQueryable<MyCustomObject> SearchSomething(string keywords)
    {
       var keywordsParam = new ObjectParameter("keywords", typeof(string)) 
                               { 
                                  Value = keywords 
                                };
        return (this as IObjectContextAdapter).ObjectContext
        .CreateQuery<MyCustomObject>(
         "MyContextType.SearchSomething(@keywords)", keywordsParam);
    }
    

    Add

    public DbSet<MyCustomObject> SearchResults { get; set; }
    

    to your DbContext class

    Add in the overriden OnModelCreating method:

    modelBuilder.Conventions
    .Add(new CodeFirstStoreFunctions.FunctionsConvention<MyContextType>("dbo"));
    

    And now you can call/join with a table values function like this:

    CREATE FUNCTION SearchSomething
    (   
        @keywords nvarchar(4000)
    )
    RETURNS TABLE 
    AS
    RETURN 
    (SELECT KEY_TBL.RANK AS Rank, Id
    FROM MyTable 
    LEFT JOIN freetexttable(MyTable , ([MyColumn1],[MyColumn2]), @keywords) AS KEY_TBL      
    ON MyTable.Id = KEY_TBL.[KEY]  
    WHERE KEY_TBL.RANK > 0   
    )
    GO
    
    0 讨论(0)
提交回复
热议问题